【opencv小案例-对象提取】阈值分割+形态学处理+面积横纵比过滤

在图像处理中我们常常需要提取目标图像中的ROI区域或这是某个形状,这样我们就需要观察对象的特征,根据它的特征去提取。
这次我们在下图中提取其中的圆
【opencv小案例-对象提取】阈值分割+形态学处理+面积横纵比过滤_第1张图片

基本思路

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
	/*vectorMycircle;
	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;
}

效果图:
【opencv小案例-对象提取】阈值分割+形态学处理+面积横纵比过滤_第2张图片

你可能感兴趣的:(opencv,小案例)