通过寻找轮廓的中心,以便对此进行旋转,校正;
计算方法:
即不同方向的矩进行运算;
static int calCoutorCenter(char* Imgname, vector<Point2f> & mc, double minarea = 0, double whRatio = 1);
int main()
{
char* filename = new char[50];
strcpy(filename, "../image/rl_4.jpg");
//getContoursByCplus(filename);
vector<Point2f> mc;
calCoutorCenter(filename, mc);
delete[] filename;
return 0;
}
API实现转自 opencv ref.
static int calCoutorCenter(char* Imgname, vector<Point2f> & mc, double minarea, double whRatio)
{
RNG rng(12345);
cv::Mat src, dst, canny_output;
/// Load source image and convert it to gray
src = imread(Imgname, 0);
if (!src.data)
{
std::cout << "read data error!" << std::endl;
return -1;
}
blur(src, src, Size(3, 3));
//the pram. for findContours,
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// Detect edges using canny
Canny(src, canny_output, 80, 255, 3);
/// Find contours
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
//CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE
double maxarea = 0;
int maxAreaIdx = 0;
for (int i = 0; i<contours.size(); i++)
{
double tmparea = fabs(contourArea(contours[i]));
if (tmparea>maxarea)
{
maxarea = tmparea;
maxAreaIdx = i;
continue;
}
if (tmparea < minarea)
{
//删除面积小于设定值的轮廓
contours.erase(contours.begin() + i);
std::wcout << "delete a small area" << std::endl;
continue;
}
//计算轮廓的直径宽高
Rect aRect = boundingRect(contours[i]);
if ((aRect.width / aRect.height)<whRatio)
{
//删除宽高比例小于设定值的轮廓
contours.erase(contours.begin() + i);
std::wcout << "delete a unnomalRatio area" << std::endl;
continue;
}
}
/// Get the moments
vector<Moments> mu(contours.size());
for (int i = 0; i < contours.size(); i++)
{
mu[i] = moments(contours[i], false);
}
/// Get the mass centers:
vector<Point2f> mc(contours.size());
for (int i = 0; i < contours.size(); i++)
{
mc[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
std::cout << "mc[" << i << "]=" << mc[i].x << "," << mc[i].y << std::endl;
}
/// Draw contours,彩色轮廓
dst = Mat::zeros(canny_output.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
//随机颜色
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point());
circle(dst, mc[i], 4, color, -1, 8, 0);
}
// Create Window
char* source_window = "countors";
namedWindow(source_window, CV_WINDOW_NORMAL);
imshow(source_window, dst);
imwrite("dst.jpg", dst);
cv:; waitKey(0);
return 0;
}