在图像处理中我们常常需要提取目标图像中的ROI区域或这是某个形状,这样我们就需要观察对象的特征,根据它的特征去提取。
这次我们在下图中提取其中的圆
基本思路
1、二值化处理
2、形态学操作(开与闭)去除干扰
3、提取轮廓,通过轮廓的面积大小与横纵比过滤
4、获取目标图像数据并标记
代码
# include<opencv2\opencv.hpp>
# include <iostream>
# include <math.h>
using namespace std;
using namespace cv;
Mat src, dst,binary;
int main(int argc, char** argv) {
src = imread("E:/tuku/case003.png",IMREAD_GRAYSCALE);
if (src.empty()) {
cout << "can't find this picture...";
return -1;
}
Rect roi = Rect(30, 30, src.cols - 50, src.rows - 50);
Mat ROI = src(roi);
imshow("input", ROI);
//二值化
threshold(ROI, binary, 0, 255, THRESH_BINARY_INV|THRESH_OTSU);
imshow("binary Image", binary);
//形态学操作(先闭操作再开操作)
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(binary, dst, MORPH_CLOSE, kernel);
imshow("colse Image", dst);
kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(dst, dst, MORPH_OPEN, kernel);
imshow("open Image", dst);
//提取轮廓
vector<vector<Point>> contours;
vector<Vec4i>hierachy;
findContours(dst, contours, hierachy, RETR_TREE,CHAIN_APPROX_SIMPLE,Point(-1,-1));
Mat ResultImage = Mat::zeros(ROI.size(), CV_8UC3);
//Mat circleImage = ROI.clone();
//cvtColor(circleImage, circleImage, COLOR_GRAY2BGR);
Point cc;
for (size_t t = 0; t < contours.size(); t++) {
//面积过滤
double area = contourArea(contours[t]);
if (area < 150)continue;
//横纵比过滤
Rect rect = boundingRect(contours[t]);//最小的外接矩形
float radio = float(rect.height) / float(rect.width);
if (radio<1.1&&radio>0.9) {
drawContours(ResultImage, contours, t, Scalar(0, 0, 255), -1, 8, Mat(), 0, Point());
printf("circle area :%f\n", area);
printf("circle length:%f\n", arcLength(contours[t], true));//周长计算
int x = rect.x + rect.width / 2;
int y = rect.y + rect.height / 2;
cc = Point(x, y);
circle(ResultImage, cc, 2, Scalar(0, 0, 255), 2, 8, 0);
printf("圆心坐标:(%d,%d)", x, y);
}
}
imshow("result Image", ResultImage);
Mat circleImage = ROI.clone();
cvtColor(circleImage, circleImage, COLOR_GRAY2BGR);
circle(circleImage, cc, 2, Scalar(0, 0, 255), 2, 8, 0);
imshow("Final Result Image", circleImage);
//detect circle
/*vector<Vec3f>Mycircle;
Mat grat_result;
cvtColor(ResultImage, grat_result, COLOR_GRAY2BGR);
HoughCircles(grat_result, Mycircle, HOUGH_GRADIENT, 1, 7, 50, 20, 23, 100);
Mat circleImage = ROI.clone();
cvtColor(circleImage, circleImage, COLOR_GRAY2BGR);
for (int i = 0; i < Mycircle.size(); i++) {
Vec3f circleInfo = Mycircle[i];
circle(circleImage, Point(circleInfo[0], circleInfo[1]), circleInfo[2], Scalar(0, 0, 255), 2, 8, 0);
}
imshow("Final Result Image", circleImage);*/
waitKey(0);
return 0;
}
效果图: