Creating .avi video from .jpg images in opencv - visual-studio-2010

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv[])
{
Mat image;
image = imread("C:/Users/Abhilash/Desktop/myFrames/frame1.jpg",1);
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << endl ;
return -1;
}
gets size of the frame
Size s = image.size();
double dWidth = s.height;
double dHeight = s.width;
cout << "Frame Size = " << dWidth << "x" << dHeight << endl;
Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));
Initializing videowriter
VideoWriter oVideoWriter ("D:/MyVideo.avi", CV_FOURCC('P','I','M','1'), 25,
frameSize, true);
if ( !oVideoWriter.isOpened() ) //if not initialize the VideoWriter successfully, exit the program
{
cout << "ERROR: Failed to write the video" << endl;
return -1;
}
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
int i;
char buffer[50];
Reading the images and adding them to video file
for(i=1;i<=250;i++) //putting 250 frames to MyVideo
{
Mat frame;
sprintf(buffer,"C:/Users/Abhilash/Desktop/myFrames/frame%d.jpg",i);
frame = imread(buffer,1);
if(! frame.data ) // Check for invalid input
{
cout << "Could not open or find the image" << endl ;
return -1;
}
oVideoWriter << (frame); //writer the frame into the file
imshow("MyVideo", frame); //show the frame in "MyVideo" window
if (waitKey(10) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}
This code reads 250 .jpg frames and displays them properly. The size of the video file created is 5.54KB. But I am not able to play the video file(in KMPlayer).

Related

OpenCV perspectiveTransform broken function

Im trying to use perspectiveTransform but I keep getting error. I tried to follow the solution from this thread http://answers.opencv.org/question/18252/opencv-assertion-failed-for-perspective-transform/
_players[i].getCoordinates() is of type Point
_homography_matrix is a 3 x 3 Mat
Mat temp_Mat = Mat::zeros(2, 1, CV_32FC2);
for (int i = 0; i < _players.size(); i++)
{
cout << Mat(_players[i].get_Coordinates()) << endl;
perspectiveTransform(Mat(_players[i].get_Coordinates()), temp_Mat, _homography_matrix);
}
Also, how do I convert temp_Mat into type Point ?
OpenCV Error: Assertion failed (scn + 1 == m.cols) in cv::perspectiveTransform
Basically you just need to correct from
Mat(_players[i].get_Coordinates()) ...
to
Mat2f(_players[i].get_Coordinates()) ...
In the first case you are creating a 2x1, 1 channel float matrix, in the second case (correct) you create a 1x1, 2 channel float matrix.
You also don't need to initialize temp_Mat.
You can also use template Mat_ to better control the types of your Mats. E.g. creating a Mat of type CV_32FC2 is equivalent to create a Mat2f.
This sample code will show you also how to convert back and forth between Mat and Point:
#include <opencv2\opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
// Some random points
vector<Point2f> pts = {Point2f(1,2), Point2f(5,10)};
// Some random transform matrix
Mat1f m(3,3, float(0.1));
for (int i = 0; i < pts.size(); ++i)
{
cout << "Point: " << pts[i] << endl;
Mat2f dst;
perspectiveTransform(Mat2f(pts[i]), dst, m);
cout << "Dst mat: " << dst << endl;
Point2f p(dst(0));
cout << "Dst point: " << p << endl;
}
return 0;
}

Windows - sound recording program giving noise

I wrote the following program to record the sound through soundcard in windows and print the PCM data from buffer of waveheader. But it gives only the data 32600-32700. Is the problem with my soundcard? I have used WAVE_MAPPER which automatically selects the source...Please help me
#include <Windows.h>
#include <MMSystem.h>
#include <iostream>
using namespace std;
int main(){
HWAVEIN microHandle;
WAVEHDR waveHeader;
MIXERCAPS mixerCaps;
WAVEFORMATEX format;
//HWAVEOUT hwo; // play
while (1){
const int NUMPTS = 44100 * 0.01; // 10 seconds
int sampleRate = 44100; //can get frequency from here
short int waveIn[NUMPTS]; // 'short int' is a 16-bit type; I request 16-bit samples below
// for 8-bit capture, you'd use 'unsigned char' or 'BYTE' 8-bit types
MMRESULT result = 0;
format.wFormatTag = WAVE_FORMAT_PCM; // simple, uncompressed format
format.wBitsPerSample = 8; // 16 for high quality, 8 for telephone-grade
format.nChannels = 1; // 1=mono, 2=stereo
format.nSamplesPerSec = sampleRate; // 22050
format.nAvgBytesPerSec = format.nSamplesPerSec*format.nChannels*format.wBitsPerSample / 8;
// = nSamplesPerSec * n.Channels * wBitsPerSample/8
format.nBlockAlign = format.nChannels*format.wBitsPerSample / 8;
// = n.Channels * wBitsPerSample/8
format.cbSize = 0;
result = waveInOpen(&microHandle, WAVE_MAPPER, &format, 0L, 0L, WAVE_FORMAT_DIRECT);
cout << "checking step 1" << endl;
if (result)
{
cout << "Fail step 1" << endl;
cout << result << endl;
Sleep(10000);
return 0;
}
// Set up and prepare header for input
waveHeader.lpData = (LPSTR)waveIn;
waveHeader.dwBufferLength = NUMPTS;// *2;//why *2
waveHeader.dwBytesRecorded = 0;
waveHeader.dwUser = 0L;
waveHeader.dwFlags = 0L;
waveHeader.dwLoops = 0L;
waveInPrepareHeader(microHandle, &waveHeader, sizeof(WAVEHDR));
// Insert a wave input buffer
result = waveInAddBuffer(microHandle, &waveHeader, sizeof(WAVEHDR));
int NumOfMixers = mixerGetNumDevs();
cout << NumOfMixers << endl;
//cout<<(char*)mixerCaps.szPname<<endl;
//system("pause");
cout << "checking step 2" << endl;
if (result)
{
cout << "Fail step 2" << endl;
cout << result << endl;
Sleep(10000);
return 0;
}
//system("pause");
result = waveInStart(microHandle);
cout << "checking step 3......started recording..." << endl;
if (result)
{
cout << "Fail step 3" << endl;
cout << result << endl;
Sleep(10000);
return 0;
}
// Wait until finished recording
do { cout << "still"; } while (waveInUnprepareHeader(microHandle, &waveHeader, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING);
waveInStop(microHandle);
waveInReset(microHandle);
//waveInUnprepareHeader(hwi, lpWaveHdr, sizeof(WAVEHDR));
waveInClose(microHandle);
//printing the buffer
for (int i = 0; i < waveHeader.dwBufferLength; i++)
{
if (waveIn[i] > 0)
cout << i << "\t" << waveIn[i] << endl;
}
}
system("pause");
//waveInClose(microHandle);
return 0;
}
I would be very grateful if someone could help me...
One obvious problem is that you're mixing the usage of 16 and 8 bits. You're buffer is defined as a 16-bit short. Notice your own comment:
short int waveIn[NUMPTS]; // 'short int' is a 16-bit type; I request 16-bit samples below
// for 8-bit capture, you'd use 'unsigned char' or 'BYTE' 8-bit types
Yet, when defining the audio format you are specifying 8 bits:
format.wBitsPerSample = 8; // 16 for high quality, 8 for telephone-grade
Either change format.wBitsPerSample = 16 or if you want 8 bit audio then do something like this:
unsigned char waveIn[NUMPTS];
...
format.wBitsPerSample = 8; // 16 for high quality, 8 for telephone-grade
//printing the buffer
for (int i = 0; i < waveHeader.dwBufferLength; i++)
{
cout << i << "\t" << (int)waveIn[i] << endl;
}

ReadProcessMemory returns the same data for any address

Working on WinXP SP3.
Visual Studio 2005.
Trying to read memory of another process.
std::cout<<"Reading Process Memory\n";
const DWORD pid = 3476;
HANDLE handle = OpenProcess(PROCESS_VM_READ,FALSE,pid);
if(handle == NULL) {std::cout<<"Failed to open process\n";return 0;}
char* buffer1 = new char[256];
char* buffer2 = new char[256];
memset(buffer1,0,256*sizeof(char));
memset(buffer2,0,256*sizeof(char));
DWORD nbr = 0;
int address = 0x400000;
BOOL result = ReadProcessMemory(handle,&address,buffer1,32,&nbr);
if(result!=1) std::cout<<"Failed to read memory\n";
address = 0x400000+0x1000;
result = ReadProcessMemory(handle,&address,buffer2,32,&nbr);
if(result!=1) std::cout<<"Failed to read memory\n";
int i = 0;
while(i++<10)
{
if(buffer1[i]!=buffer2[i]) {std::cout<<"Buffers are different\n";break;}
}
delete[] buffer1;
delete[] buffer2;
CloseHandle(handle);
std::cin>>i;
return 0;
The problem is that both buffers are getting the same values. ReadProcMemory returns 1 and number of bytes read is the same as requested.
Your calls to ReadProcessMemory are incorrect. You should be using address directly, not &address. You may need to cast it to a const void *.
result = ReadProcessMemory(handle, reinterpret_cast<const void *>(address), buffer, 32, &nbr);
And you probably should declaring address as a type large enough to handle a pointer, like std::ssize_t or INT_PTR.
INT_PTR address = 0x400000;
buffer couldn't be a char, it has to be int, thats a working example
#include <windows.h>
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
int point1=0;
int i=0;
int d=0;
char* value[4];
SIZE_T stBytes = 0;
HWND hwnd;
HANDLE phandle;
DWORD pid;
hwnd = FindWindow(NULL, "calc"); // calc is the name of the windows process
if (hwnd != 0) {
GetWindowThreadProcessId(hwnd, &pid);
phandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
} else {
cout << "process is not executing";
cin.get();
return 0;
}
if (phandle != 0) {
for(i=0;i<4;i++) // 4 or wathever
{
cout << "The pointer is 0x1001000" << endl; //Print the pointer
ReadProcessMemory(phandle, (LPVOID)0x1001000+i, &point1, 4, &stBytes); //Get the content from 0x1001000 and store it in point1
cout << "decimal content point1 " << point1 << " (DEC)" << endl; //Print the decimal content of point1
printf("%x \n",point1); // print hexadecimal content of point1
char *p=(char*)&point1; // point point1 buffer
for(d=0;d<4;d++)
printf("%x",(unsigned int)(unsigned char) *(p+d)); // print backwards (because the buffer is like a LIFO) and see the dbg debugger
}
ReadProcessMemory(phandle, (LPVOID)point1, &value, 6, &stBytes); //Get the value that is in the address pointed by the pointer
cout << "The value in the non-static address is " << (char*)value << endl << endl; //Print the value
cout << "Press ENTER to exit." << endl;
cin.get();
} else {
cout << "Couldn't get a handle";
cin.get();
// address 0x1001000 content hex 5278DA77
}
}

Why the audio recorder code can work for 8 bit, but cannot work for 16 bit??

I am trying to record the audio at windows, here is my code. it works well for 8 bit, but it cannot work for 16 bit. Can anyone help me?
#include
#include
#include
#pragma comment(lib,"winmm.lib")
using namespace std;
int test(){
HWAVEIN microHandle;
WAVEHDR waveHeader;
MMRESULT result = 0;
WAVEFORMATEX waveformat;
waveformat.wFormatTag = WAVE_FORMAT_PCM;
waveformat.wBitsPerSample=8;
waveformat.nSamplesPerSec=16000;//8000;
waveformat.nAvgBytesPerSec=waveformat.nSamplesPerSec*waveformat.nSamplesPerSec/8;
waveformat.nChannels=1;
waveformat.nBlockAlign=waveformat.nChannels*waveformat.wBitsPerSample/8;
waveformat.cbSize=0;
result = waveInOpen(&microHandle, WAVE_MAPPER, &waveformat, 0L, 0L, CALLBACK_EVENT);
if (result)
{
cout << "Fail step 1" << endl;
cout << result << endl;
Sleep(10000);
return 0;
}
const int BUFSIZE = 16000*4;
char * buf = (char *)malloc(BUFSIZE);
// Set up and prepare header for input
waveHeader.lpData = (LPSTR)buf;
waveHeader.dwBufferLength = BUFSIZE;
waveHeader.dwBytesRecorded=0;
waveHeader.dwUser = 0L;
waveHeader.dwFlags = 0L;
waveHeader.dwLoops = 0L;
waveInPrepareHeader(microHandle, &waveHeader, sizeof(WAVEHDR));
// Insert a wave input buffer
result = waveInAddBuffer(microHandle, &waveHeader, sizeof(WAVEHDR));
if (result)
{
cout << "Fail step 2" << endl;
cout << result << endl;
Sleep(10000);
return 0;
}
result = waveInStart(microHandle);
if (result)
{
cout << "Fail step 3" << endl;
cout << result << endl;
Sleep(10000);
return 0;
}
// Wait until finished recording
do {} while (waveInUnprepareHeader(microHandle, &waveHeader, sizeof(WAVEHDR))==WAVERR_STILLPLAYING);
FILE *fp = fopen("output.pcm","w");
fwrite(buf,1,BUFSIZE,fp);
fclose(fp);
waveInClose(microHandle);
return 0;
}
void main()
{
test();
}
If I set the parameter waveformat.wBitsPerSample = 8, it can record the audio correctly,
but if i set it waveformat.wBitsPerSample = 16, it record the Noise!!!
Can anyone help me?
thanks.
it should bu FILE *fp = fopen("output.pcm","wb"); NOT FILE *fp = fopen("output.pcm","w");

Get RGB pixels from input image and reconstruct an output image in opencv

I want to load the image in opencv and split the image into channels(RGB) and i want to increase any one of the colors and getting that corresponding output image.is there any easiest way to do this problem?
Well to add any scalar to an RGB image you can use cvAddS(srcImage, scalarToAdd, dstImage).
Here is an example:
int main(int argc, char** argv)
{
// Create a named window with the name of the file.
cvNamedWindow( argv[1], 1 );
// Load the image from the given file name.
IplImage* img = cvLoadImage( argv[1] );
//Make a scalar to add 30 to Blue Color and 20 to Red (BGR format)
CvScalar colorAdd = cvScalar(30.0, 0, 20.0);
cvAddS(img, colorAdd, img);
// Show the image in the named window
cvShowImage( argv[1], img );
// Idle until the user hits the “Esc” key.
while( 1 ) {
if( cvWaitKey( 100 ) == 27 ) break;
}
cvDestroyWindow( argv[1] );
cvReleaseImage( &img );
exit(0);
}
Haven't tested the code, hope it helps.
#karlphillip: Generally a better solution for RGB images - handles any padding at row ends, also parallelizes nicely with OMP !
for (int i=0; i < height;i++)
{
unsigned char *pRow = pRGBImg->ptr(i);
for (int j=0; j < width;j+=bpp)
// For educational puporses, here is how to print each R G B channel:
std::cout << std::dec << "R:" << (int) pRow->imageData[j] <<
" G:" << (int) pRow->imageData[j+1] <<
" B:" << (int) pRow->imageData[j+2] << " ";
}
}
With the OpenCV C++ interface you can simply add a Scalar to an image with the overloaded arithmetic operators.
int main(int argc, const char * argv[]) {
cv::Mat image;
// read an image
if (argc < 2)
return 2;
image = cv::imread(argv[1]);
if (!image.data) {
std::cout << "Image file not found\n";
return 1;
}
cv::Mat image2 = image.clone(); // Make a deep copy of the image
image2 += cv::Scalar(30,0,20); // Add 30 to blue, 20 to red
cv::namedWindow("original");
cv::imshow("original", image);
cv::namedWindow("addcolors");
cv::imshow("addcolors", image2);
cv::waitKey(0);
return 0;
}
Another option is to manually iterate on the pixels of the image and work on the channel that interests you. This will give you the flexibility to manipulate each channel individually or as a group.
The following code uses the C interface of OpenCV:
IplImage* pRGBImg = cvLoadImage("test.png", CV_LOAD_IMAGE_UNCHANGED);
int width = pRGBImg->width;
int height = pRGBImg->height;
int bpp = pRGBImg->nChannels;
for (int i=0; i < width*height*bpp; i+=bpp)
{
// For educational puporses, here is how to print each R G B channel:
std::cout << std::dec << "R:" << (int) pRGBImg->imageData[i] <<
" G:" << (int) pRGBImg->imageData[i+1] <<
" B:" << (int) pRGBImg->imageData[i+2] << " ";
}
However, if you want to add a fixed value to a certain channel you might want to check #Popovici's answer.

Resources