I need to extract contour of shapes in images, and get the fitted ellipse. However, when I use the following code, the result is not very satisfying.
#include "stdafx.h"
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include
<fstream> <fstream>
using namespace std;
using namespace cv;
extern void Threshold(Mat gray, Mat& binary);
extern void Not(Mat&
im); im);
// Calculate the contour of connected region
// erease the image that is too large or too small
void
getSizeContours(vector<vector<point>> getSizeContours(vector<vector<Point>> &contours)
{
int cmin = 10; // min contour length
int cmax = 10000; // max contour length
vector<vector<point>>::const_iterator
vector<vector<Point>>::const_iterator itc = contours.begin();
while(itc != contours.end())
{
if((itc->size()) < cmin || (itc->size()) > cmax)
{
itc = contours.erase(itc);
}
else ++ itc;
}
}
// Calculate min convex oval
void MinConvexOval(Mat gray,
vector<vector<point>> vector<vector<Point>> &contours,
vector<mat> vector<Mat> oval_result)
{
Mat
oval(gray.rows3,gray.cols3,CV_8UC3);
vector<vector<point>>::const_iterator oval(gray.rows*3,gray.cols*3,CV_8UC3);
vector<vector<Point>>::const_iterator itc=contours.begin();
while(itc != contours.end())
{
double
perimeter=arcLength(itc,true);
perimeter=arcLength(*itc,true);
double area=
contourArea(itc,false);
contourArea(*itc,false);
Rect
rect=boundingRect(itc);
rect=boundingRect(*itc);
CvBox2D
box=minAreaRect(itc);
box=minAreaRect(*itc);
Point pt1, pt2;
pt1.x=rect.x;
pt1.y=rect.y;
pt2.x=rect.x+rect.width;
pt2.y=rect.y+rect.height;
RotatedRect box2=fitEllipse(*itc);
ellipse(oval, box2, Scalar(255,0,255), 1, 8);
Point2f vertices[4];
box2.points(vertices);
for (int i = 0; i < 4; i++)
line(oval, vertices[i], vertices[(i+1)%4], Scalar(0,255,0));
++itc;
}
drawContours(oval,contours,-1, Scalar(0,255,255), 1);
imshow("oval",oval);
waitKey(0);
}
}
void cvText(Mat img, const char* text, int x, int y)
{
CvFont
font;
font;
double hscale = 1.0;
double vscale = 1.0;
int linewidth = 2;
cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX |CV_FONT_ITALIC,hscale,vscale,0,linewidth);
Scalar textColor =Scalar(0,255,255);
Point textPos =Point(x, y);
putText(img, text, textPos, CV_FONT_HERSHEY_COMPLEX, 1,textColor);
}
}
void GetContour(Mat grayim)
{
Mat binaryim;
Threshold(grayim, binaryim); //
binaryzation
binaryzation
vector<vector<Point>> contours;
//CV_CHAIN_APPROX_NONE Get all of the pixels of the contours
findContours(binaryim, contours, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
getSizeContours(contours);
vector<Mat> oval_result;
MinConvexOval(grayim,contours,oval_result);
}
}
Testing image:
image:
Result image:
image:
The fitting result of the right-down shape is wrong, could anyone help me, please? Thanks a lot!