I have one function dealing with image. In that function, i am trying to find several particular ellipses. The code is working if i call it individually in a separate project, but in the whole project, it crashed when it returns.
I used many vectors in the processing to store some information during the process.
The error information:
Windows has triggered a breakpoint in KinectBridgeWithOpenCVBasics-D2D.exe.
This may be due to a corruption of the heap, which indicates a bug in KinectBridgeWithOpenCVBasics-D2D.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while KinectBridgeWithOpenCVBasics-D2D.exe has focus.
The output window may have more diagnostic information.
could any one tell me where is wrong to cause this crash. More weird is it is working in the separate project.
The code is a little long, but it is really noting, just looking for several particular ellipses with some pattern.
Thank you.
int FindNao(Mat* pImg, double* x, double* y)
{
// Fail if pointer is invalid
if (!pImg)
{
return 2;
}
// Fail if Mat contains no data
if (pImg->empty())
{
return 3;
}
//*x = 0; *y = 0;
Mat localMat = *pImg; // save a local copy of the image
cvtColor(~localMat, localMat, CV_BGR2GRAY); // Convert to gray image
threshold(localMat, localMat, 165, 255, THRESH_BINARY); // Convert into black-white image
Mat elementOpen = getStructuringElement(MORPH_ELLIPSE, Size(5,5), Point(-1,-1));
morphologyEx(localMat, localMat, MORPH_OPEN, elementOpen, Point(-1,-1), 1);
// Find all the contours in the blak-white image
vector<vector<Point>> contours;
findContours(localMat.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
localMat.release();
// Calculate the area of each contour
vector<double> areas; int num = contours.size();
/* If no contours are found, return S_OK */
if(num < 1)
return 1;
for(int i = 0; i < num; i++)
{
areas.push_back(contourArea(contours[i]));
}
// First round of selection
// The area is small, and they are like a ellipse and around the middle in X direction and at the upper part of the image
vector<RotatedRect> selected_ellipses; // store the fitted ellipse fitted to the potential contour
vector<double> selected_areas; // store the contour area of the potential contour
int imgX = localMat.cols; int imgY = localMat.rows; // get the demension of the image
for(int i=0; i < num - 1; i++)
{
if(areas[i] < 350 && areas[i] > 10)
{
// fit an ellipse
RotatedRect ellipse1 = fitEllipse(Mat(contours[i]));
// it is a reasonable ellipse, and the area should be close to the
double length1 = ellipse1.size.height;
double length2 = ellipse1.size.width;
if( abs(1 - length1/length2) <= 0.8 &&
abs(1 - areas[i] / (CV_PI * length1 * length2 / 4) ) <= 0.2 )
{
selected_ellipses.push_back(ellipse1);
selected_areas.push_back(areas[i]);
}
}
}
/************ Second round of selection **************/
// Calculate each ellipse's dimension
vector<double> diff_dimension;
vector<double> ave_dimention;
/* If no contours are found, return S_OK */
if(selected_ellipses.size() < 1)
return 1;
for(int i = 0; i < selected_ellipses.size(); i++)
{
double difference = abs(1 - selected_ellipses[i].size.height / selected_ellipses[i].size.width);
diff_dimension.push_back(difference);
double average = (selected_ellipses[i].size.height + selected_ellipses[i].size.width) / 2;
ave_dimention.push_back(average);
}
vector<vector<int>> eyematches;
vector<vector<int>> cammatches;
// go over all the ellipses to find the matches with close area and dimension.
for(int i = 0; i < selected_ellipses.size() - 1; i++)
{
for(int j = i+1; j < selected_ellipses.size(); j++)
{
// looking for the eyes
if(diff_dimension[i] < 0.05 && diff_dimension[j] < 0.05)
{
double diff_area = abs( 1 - selected_areas[i] / selected_areas[j] );
if (diff_area < 0.05)
{
double diff_y = abs(selected_ellipses[i].center.y - selected_ellipses[j].center.y);
if(diff_y < 10)
{
vector<int> match1;
match1.push_back(i); match1.push_back(j);
eyematches.push_back(match1);
}
}
}
// looking for the cameras
double diff_x = abs(selected_ellipses[i].center.x - selected_ellipses[j].center.x);
if (diff_x < 10)
{
vector<int> match2;
match2.push_back(i); match2.push_back(j);
cammatches.push_back(match2);
}
}
}
/* Last check */
int num_eyes = eyematches.size();
int num_cams = cammatches.size();
if(num_eyes == 0 || num_cams == 0)
return 1;
// Calculate the vector between two eyes and the center
vector<Point> vector_eyes; vector<Point> center_eyes;
vector<vector<int>>::iterator ite = eyematches.begin();
while(ite < eyematches.end())
{
Point point;
point.x = selected_ellipses[(*ite)[0]].center.x - selected_ellipses[(*ite)[1]].center.x;
point.y = selected_ellipses[(*ite)[0]].center.y - selected_ellipses[(*ite)[1]].center.y;
vector_eyes.push_back(point);
point.x = (selected_ellipses[(*ite)[0]].center.x + selected_ellipses[(*ite)[1]].center.x)/2;
point.y = (selected_ellipses[(*ite)[0]].center.y + selected_ellipses[(*ite)[1]].center.y)/2;
center_eyes.push_back(point);
ite++;
}
// Calculate the vector between two cameras and the center
vector<Point> vector_cams; vector<Point> center_cams;
ite = cammatches.begin();
while(ite < cammatches.end())
{
Point point;
point.x = selected_ellipses[(*ite)[0]].center.x - selected_ellipses[(*ite)[1]].center.x;
point.y = selected_ellipses[(*ite)[0]].center.y - selected_ellipses[(*ite)[1]].center.y;
vector_cams.push_back(point);
point.x = (selected_ellipses[(*ite)[0]].center.x + selected_ellipses[(*ite)[1]].center.x)/2;
point.y = (selected_ellipses[(*ite)[0]].center.y + selected_ellipses[(*ite)[1]].center.y)/2;
center_cams.push_back(point);
ite++;
}
// Match the eyes and cameras, by calculating the center distances and intersection angle
vector<vector<int>> matches_eye_cam;
vector<vector<double>> matches_parameters;
for(int i = 0; i < num_eyes; i++)
{
for(int j = 0; j < num_cams; j++)
{
vector<int> temp1;
vector<double> temp2;
// calculate the distances
double distance = sqrt( double( (center_eyes[i].x - center_cams[j].x)^2 + (center_eyes[i].y - center_cams[j].y)^2 ) );
// calculate the cosine intersection angle
double cosAngle = vector_eyes[i].x * vector_cams[j].x + vector_eyes[i].y * vector_cams[j].y;
// store everything
temp1.push_back(i); temp1.push_back(j);
temp2.push_back(distance); temp2.push_back(cosAngle);
matches_eye_cam.push_back(temp1);
matches_parameters.push_back(temp2);
}
}
// go over to find the minimum
int min_dis = 0; int min_angle = 0;
vector<vector<double>>::iterator ite_para = matches_parameters.begin();
/* If no contours are found, return S_OK */
if(matches_parameters.size() < 1)
return 1;
for(int i = 1; i < matches_parameters.size(); i++)
{
if( (*(ite_para+min_dis))[0] > (*(ite_para+i))[0] )
min_dis = i;
if( (*(ite_para+min_angle))[1] > (*(ite_para+i))[1] )
min_angle = i;
}
// get the best match of eyes and cameras 's index
int eyes_index, cams_index;
vector<vector<int>>::iterator ite_match_eye_cam = matches_eye_cam.begin();
if(min_dis == min_angle)
{
// perfect match
eyes_index = (*(ite_match_eye_cam + min_dis))[0];
cams_index = (*(ite_match_eye_cam + min_dis))[1];
}
else
{
// tried to fuse them and find a better sulotion, but didnot work out, so
// go with the min_dis
eyes_index = (*(ite_match_eye_cam + min_dis))[0];
cams_index = (*(ite_match_eye_cam + min_dis))[1];
}
vector<vector<int>>::iterator ite_eyes = eyematches.begin();
vector<vector<int>>::iterator ite_cams = cammatches.begin();
// draw the eyes
ellipse(*pImg, selected_ellipses[(*(ite_eyes+eyes_index))[0]], Scalar(0, 255, 255), 2, 8);
ellipse(*pImg, selected_ellipses[(*(ite_eyes+eyes_index))[1]], Scalar(0, 255, 255), 2, 8);
// draw the camera
ellipse(*pImg, selected_ellipses[(*(ite_cams+cams_index))[0]], Scalar(0, 255, 0), 2, 8);
ellipse(*pImg, selected_ellipses[(*(ite_cams+cams_index))[1]], Scalar(0, 255, 0), 2, 8);
imshow("show", *pImg);
// find the upper camera
int m1 = (*(ite_cams+cams_index))[0];
int m2 = (*(ite_cams+cams_index))[1];
int upper;
if(selected_ellipses[m1].center.y < selected_ellipses[m2].center.y)
upper = m1;
else
upper = m2;
*x = selected_ellipses[upper].center.x;
*y = selected_ellipses[upper].center.y;
return 1;
}
int main()
{
Mat imO = imread("Capture.PNG");
double x, y;
FindNao(&imO, &x, &y);
cout<<x<<" "<<y<<endl;
cvWaitKey(0);
}