|
OpenCV cvCreateImage() problem
This program takes a video with three moving objects, finds those objects in each frame and saves their location. Then it pulls a non-moving background image out of the video and displays it. In other words, it disects a video into a background image and template image paths of the moving objects. Then it attempts to recreate the video using the background image and the location of the templates for each frame.
But I'm getting a major error that won't let me continue. Lines 50-52 all involve calculating the Normalized Cross Correlation for each template image. For some reason it is giving me a crazy error and fails right there every time.
Any suggestions?
#include <iostream>
#include <cv.h>
#include <highgui.h>
#include <Math.h>
#include <cxmisc.h>
using namespace std;
struct runningCount
{
unsigned char indexR; //index to let me know what the next open slot is to insert an intensity value
unsigned char indexG;
unsigned char indexB;
short int countR[5]; //keeps a count of how many times we've gone over that intensity
short int countG[5];
short int countB[5];
unsigned char intensityR[5]; //saves 5 different intensity values
unsigned char intensityG[5];
unsigned char intensityB[5];
};
int main(int argc, char *argv[])
{
runningCount pixelVals[128][96];
CvCapture *video;
CvCapture *video1;
IplImage *templateRImage = NULL;
IplImage *templateGImage = NULL;
IplImage *templateBImage = NULL;
IplImage *videoImage = NULL;
IplImage *background = NULL;
IplImage *NCCImageR = NULL;
IplImage *NCCImageG = NULL;
IplImage *NCCImageB = NULL;
short int redPath[2][400];
short int bluePath[2][400];
short int greenPath[2][400];
//Setup the viewing window
cvNamedWindow("background image", 1);
video1 = cvCreateFileCapture("c:/bouncing_ball.divx");
templateRImage = cvLoadImage("c:/ball.bmp");
templateGImage = cvLoadImage("c:/Gball2.bmp");
templateBImage = cvLoadImage("c:/Bball.bmp");
CvSize videoSize = cvSize(cvGetCaptureProperty(video1, CV_CAP_PROP_FRAME_WIDTH ), cvGetCaptureProperty(video1, CV_CAP_PROP_FRAME_HEIGHT));
NCCImageR = cvCreateImage( cvSize(videoSize.width - templateRImage->width+1, videoSize.height - templateRImage->height+1) , IPL_DEPTH_32F, 1);
NCCImageG = cvCreateImage( cvSize(videoSize.width - templateGImage->width+1, videoSize.height - templateGImage->height+1) , IPL_DEPTH_32F, 1);
NCCImageB = cvCreateImage( cvSize(videoSize.width - templateBImage->width+1, videoSize.height - templateBImage->height+1) , IPL_DEPTH_32F, 1);
CvPoint max_locR;
double max_valR;
CvPoint max_locG;
double max_valG;
CvPoint max_locB;
double max_valB;
videoImage = cvQueryFrame(video1);
background = cvCreateImage( cvSize(videoImage->width, videoImage->height), IPL_DEPTH_8U, 3);
int LR128 = 0;
int TB96 = 0;
//hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );
int count = 1;
//For every frame in the video
for (int OMG = 0; OMG < 5; OMG++) //loops through the video to save 128x96 pixels into the background image 5 rows
{
for (int OMG2 = 0; OMG2 < 5; OMG2++) //loops through the video to save 128x96 pixels into the background image 5 columns
{
for (int j = 0; j < 96; j++) //clears the previous pixel information
{
for (int i = 0; i < 128; i++)
{
for ( int x = 0; x < 5; x++)
{
pixelVals[i][j].indexR = 0;
pixelVals[i][j].indexG = 0;
pixelVals[i][j].indexB = 0;
pixelVals[i][j].intensityR[x] = 0;
pixelVals[i][j].intensityG[x] = 0;
pixelVals[i][j].intensityB[x] = 0;
pixelVals[i][j].countR[x] = 0;
pixelVals[i][j].countG[x] = 0;
pixelVals[i][j].countB[x] = 0;
}
}
}
video = cvCreateFileCapture("c:/bouncing_ball.divx");
while(cvGrabFrame(video)) //returns 0 when grab fails... 1 otherwise
{
//IplImage* cvRetrieveFrame( CvCapture* capture );
videoImage = cvRetrieveFrame(video);
cvFlip(videoImage, NULL, 0);
if((OMG == 0) && (OMG2 == 0))
{
//calcs the NCC and matches the template
//cvMatchTemplate(const CvArr* image, const CvArr* templ, CvArr* result, int method );
cvMatchTemplate(videoImage, templateRImage, NCCImageR, CV_TM_CCORR_NORMED);
cvMatchTemplate(videoImage, templateGImage, NCCImageG, CV_TM_CCORR_NORMED);
cvMatchTemplate(videoImage, templateBImage, NCCImageB, CV_TM_CCORR_NORMED);
//void cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val,
// CvPoint* min_loc=NULL, CvPoint* max_loc=NULL, const CvArr* mask=NULL );
//
cvMinMaxLoc(NCCImageR, NULL, &max_valR, NULL, &max_locR);
cvMinMaxLoc(NCCImageG, NULL, &max_valG, NULL, &max_locG);
cvMinMaxLoc(NCCImageB, NULL, &max_valB, NULL, &max_locB);
if(max_valR > 0.9)
{
redPath[1][count] = max_locR.x;
redPath[2][count] = max_locR.y;
}
else
{
redPath[1][count] = -1;
redPath[2][count] = -1;
}
if(max_valG > 0.9)
{
greenPath[1][count] = max_locG.x;
greenPath[2][count] = max_locG.y;
}
else
{
greenPath[1][count] = -1;
greenPath[2][count] = -1;
}
if(max_valB > 0.9)
{
bluePath[1][count] = max_locB.x;
bluePath[2][count] = max_locB.y;
}
else
{
bluePath[1][count] = -1;
bluePath[2][count] = -1;
}
}
for(int j = TB96; j < TB96 + 96; j++)
{
for(int i = LR128; i < LR128 + 128; i++) //for every pixel within the 128 X 96 block
{
bool foundR = false; //resets the booleans telling us if we found a location and updated the count for the intensity
bool foundG = false;
bool foundB = false;
//is there an intensity value already stored for that pixel to compare to?
if ((pixelVals[i - LR128][j - TB96].indexR > 0) && (pixelVals[i - LR128][j - TB96].indexG > 0) && (pixelVals[i - LR128][j - TB96].indexB > 0))
{
for(int z = 0; z < pixelVals[i - LR128][j - TB96].indexR; z++) //check the values already in the intensity
{
//if the current intensity is 8 away from a previous one, adjust that count
if (((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 2] > (pixelVals[i - LR128][j - TB96].intensityR[z] - 1)
&& ((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 2] <(pixelVals[i - LR128][j - TB96].intensityR[z] + 1))
{
pixelVals[i - LR128][j - TB96].countR[z]++;
foundR = true;
}
if (((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 1] > (pixelVals[i - LR128][j - TB96].intensityG[z] - 1)
&& ((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 1] < (pixelVals[i - LR128][j - TB96].intensityG[z] + 1))
{
pixelVals[i - LR128][j - TB96].countG[z]++;
foundG = true;
}
if (((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 0] > (pixelVals[i - LR128][j - TB96].intensityB[z] - 1)
&& ((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 0] < (pixelVals[i - LR128][j - TB96].intensityB[z] + 1))
{
pixelVals[i - LR128][j - TB96].countB[z]++;
foundB = true;
}
}
//if the intensity was not within 4 of any of the existing intensities...
if(!foundR)
{
if (pixelVals[i - LR128][j - TB96].indexR < 5) //...create a new one if there is room
{
pixelVals[i - LR128][j - TB96].intensityR[pixelVals[i - LR128][j - TB96].indexR] = ((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 2];
pixelVals[i - LR128][j - TB96].countR[pixelVals[i - LR128][j - TB96].indexR]++;
pixelVals[i - LR128][j - TB96].indexR++;
}
else //... or replace an old one with the fewest count
{
int minCount = 0;
for (int x = 1; x < 5; x++)
{
if (pixelVals[i - LR128][j - TB96].countR[x] < pixelVals[i - LR128][j - TB96].countR[minCount])
{
minCount = x;
}
}
pixelVals[i - LR128][j - TB96].intensityR[minCount] = ((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 2];
pixelVals[i - LR128][j - TB96].countR[minCount] = 1;
}
}
if(!foundG) //same as above
{
if (pixelVals[i - LR128][j - TB96].indexG < 5)
{
pixelVals[i - LR128][j - TB96].intensityG[pixelVals[i - LR128][j - TB96].indexG] = ((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 1];
pixelVals[i - LR128][j - TB96].countG[pixelVals[i - LR128][j - TB96].indexG]++;
pixelVals[i - LR128][j - TB96].indexG++;
}
else
{
int minCount = 0;
for (int x = 1; x < 5; x++)
{
if (pixelVals[i - LR128][j - TB96].countG[x] < pixelVals[i - LR128][j - TB96].countG[minCount])
{
minCount = x;
}
}
pixelVals[i - LR128][j - TB96].intensityG[minCount] = ((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 1];
pixelVals[i - LR128][j - TB96].countG[minCount] = 1;
}
}
if(!foundB) //same as above
{
if (pixelVals[i - LR128][j - TB96].indexB < 5)
{
pixelVals[i - LR128][j - TB96].intensityB[pixelVals[i - LR128][j - TB96].indexB] = ((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 0];
pixelVals[i - LR128][j - TB96].countB[pixelVals[i - LR128][j - TB96].indexB]++;
pixelVals[i - LR128][j - TB96].indexB++;
}
else
{
int minCount = 0;
for (int x = 1; x < 5; x++)
{
if (pixelVals[i - LR128][j - TB96].countB[x] < pixelVals[i - LR128][j - TB96].countB[minCount])
{
minCount = x;
}
}
pixelVals[i - LR128][j - TB96].intensityB[minCount] = ((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 0];
pixelVals[i - LR128][j - TB96].countB[minCount] = 1;
}
}
}
else //if all the indexes are 0, there are no intensity values saved yet
{
pixelVals[i - LR128][j - TB96].intensityR[pixelVals[i - LR128][j - TB96].indexR] =((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 2];
pixelVals[i - LR128][j - TB96].countR[pixelVals[i - LR128][j - TB96].indexR]++;
pixelVals[i - LR128][j - TB96].indexR++;
pixelVals[i - LR128][j - TB96].intensityG[pixelVals[i - LR128][j - TB96].indexG] =((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 1];
pixelVals[i - LR128][j - TB96].countG[pixelVals[i - LR128][j - TB96].indexG]++;
pixelVals[i - LR128][j - TB96].indexG++;
pixelVals[i - LR128][j - TB96].intensityB[pixelVals[i - LR128][j - TB96].indexB] =((uchar*)(videoImage->imageData + videoImage->widthStep * j))[i * videoImage->nChannels + 0];
pixelVals[i - LR128][j - TB96].countB[pixelVals[i - LR128][j - TB96].indexB]++;
pixelVals[i - LR128][j - TB96].indexB++;
}
}
}
cout << count << endl;
count++;
}
//set the pixel values for the output image
for(int j = TB96; j < TB96 + 96; j++)
{
for(int i = LR128; i < LR128 + 128; i++) //for every pixel
{
int maxR = 0; //reset the max index
int maxG = 0;
int maxB = 0;
for (int q = 1; q < pixelVals[i - LR128][j - TB96].indexR; q++)
{
if(pixelVals[i - LR128][j - TB96].countR[q] > pixelVals[i - LR128][j - TB96].countR[maxR]) //compare to find the max count
{
maxR = q; //save the index of the max count
}
}
for (int q = 1; q < pixelVals[i - LR128][j - TB96].indexG; q++)
{
if(pixelVals[i - LR128][j - TB96].countG[q] > pixelVals[i - LR128][j - TB96].countG[maxG])
{
maxG = q;
}
}
for (int q = 1; q < pixelVals[i - LR128][j - TB96].indexB; q++)
{
if(pixelVals[i - LR128][j - TB96].countB[q] > pixelVals[i - LR128][j - TB96].countB[maxB])
{
maxB = q;
}
}
//set the pixel value to the intensity with the highest count
((uchar*)(background->imageData + background->widthStep * j))[i * background->nChannels + 2] = pixelVals[i - LR128][j - TB96].intensityR[maxR];
((uchar*)(background->imageData + background->widthStep * j))[i * background->nChannels + 1] = pixelVals[i - LR128][j - TB96].intensityG[maxG];
((uchar*)(background->imageData + background->widthStep * j))[i * background->nChannels + 0] = pixelVals[i - LR128][j - TB96].intensityB[maxB];
//cout << maxR << " " << maxG << " " << maxB << endl;
}
}
LR128 += 128;
cvReleaseCapture(&video);
}
TB96 += 96;
LR128 = 0;
}
//show the output image
cvShowImage("background image", background);
cvWaitKey();
//typedef struct CvVideoWriter CvVideoWriter;
//CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc, double fps, CvSize frame_size, int is_color=1 );
CvVideoWriter *outputVid;
outputVid = cvCreateVideoWriter("outputVid.avi", -1, 30, cvSize(640, 480), 1);
for (int newframes = 0; newframes < 300; newframes++)
{
IplImage *tempBack = background;
if (redPath[0][newframes] != -1)
{
for (int y = redPath[1][newframes]; y < redPath[1][newframes] + templateRImage->height; y++)
{
for (int x = redPath[0][newframes]; x < redPath[0][newframes] + templateRImage->width; x++)
{
((uchar*)(tempBack->imageData + tempBack->widthStep * y))[x * tempBack->nChannels + 2] = ((uchar*)(templateRImage->imageData + templateRImage->widthStep * (y - redPath[1][newframes]))[(x - redPath[0][newframes]) * templateRImage->nChannels + 2]);
((uchar*)(tempBack->imageData + tempBack->widthStep * y))[x * tempBack->nChannels + 1] = ((uchar*)(templateRImage->imageData + templateRImage->widthStep * (y - redPath[1][newframes]))[(x - redPath[0][newframes]) * templateRImage->nChannels + 1]);
((uchar*)(tempBack->imageData + tempBack->widthStep * y))[x * tempBack->nChannels + 0] = ((uchar*)(templateRImage->imageData + templateRImage->widthStep * (y - redPath[1][newframes]))[(x - redPath[0][newframes]) * templateRImage->nChannels + 0]);
}
}
}
if (greenPath[0][newframes] != -1)
{
for (int y = greenPath[1][newframes]; y < greenPath[1][newframes] + templateGImage->height; y++)
{
for (int x = greenPath[0][newframes]; x < greenPath[0][newframes] + templateGImage->width; x++)
{
((uchar*)(tempBack->imageData + tempBack->widthStep * y))[x * tempBack->nChannels + 2] = ((uchar*)(templateGImage->imageData + templateGImage->widthStep * (y - greenPath[1][newframes]))[(x - greenPath[0][newframes]) * templateGImage->nChannels + 2]);
((uchar*)(tempBack->imageData + tempBack->widthStep * y))[x * tempBack->nChannels + 1] = ((uchar*)(templateGImage->imageData + templateGImage->widthStep * (y - greenPath[1][newframes]))[(x - greenPath[0][newframes]) * templateGImage->nChannels + 1]);
((uchar*)(tempBack->imageData + tempBack->widthStep * y))[x * tempBack->nChannels + 0] = ((uchar*)(templateGImage->imageData + templateGImage->widthStep * (y - greenPath[1][newframes]))[(x - greenPath[0][newframes]) * templateGImage->nChannels + 0]);
}
}
}
if (bluePath[0][newframes] != -1)
{
for (int y = bluePath[1][newframes]; y < bluePath[1][newframes] + templateBImage->height; y++)
{
for (int x = bluePath[0][newframes]; x < bluePath[0][newframes] + templateBImage->width; x++)
{
((uchar*)(tempBack->imageData + tempBack->widthStep * y))[x * tempBack->nChannels + 2] = ((uchar*)(templateBImage->imageData + templateBImage->widthStep * (y - bluePath[1][newframes]))[(x - bluePath[0][newframes]) * templateBImage->nChannels + 2]);
((uchar*)(tempBack->imageData + tempBack->widthStep * y))[x * tempBack->nChannels + 1] = ((uchar*)(templateBImage->imageData + templateBImage->widthStep * (y - bluePath[1][newframes]))[(x - bluePath[0][newframes]) * templateBImage->nChannels + 1]);
((uchar*)(tempBack->imageData + tempBack->widthStep * y))[x * tempBack->nChannels + 0] = ((uchar*)(templateBImage->imageData + templateBImage->widthStep * (y - bluePath[1][newframes]))[(x - bluePath[0][newframes]) * templateBImage->nChannels + 0]);
}
}
}
cvWriteFrame(outputVid, tempBack);
}
return 0;
}
|