简单的形态学处理流程–标出图中硬币的位置
通过一个简单的例子——找出图像中的硬币轮廓,来简单的介绍一下形态学处理的流程。
下面是例子用到的图片:
流程
灰度化—cvtColor(sourceImage, grayImage, CV_BGR2GRAY);
阈值化—threshold(grayImage, thresholdImage, 100, 255, 0);
形态学处理 — morphologyEx()
找到并标出轮廓— findContours() 和 drawContours()
代码
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void main(){
//【1】
Mat sourceImage = imread("coin.jpg");
if (sourceImage.empty()){
cout << "can't grab a picture " << endl;
return;
}
imshow("source image", sourceImage);
//【2】 转换为灰度图
Mat grayImage;
cvtColor(sourceImage, grayImage, CV_BGR2GRAY);
imshow("gray image", grayImage);
//【3】 阈值化
Mat thresholdImage;
threshold(grayImage, thresholdImage, 100, 255, 0);
imshow("threshold image", thresholdImage);
//【4】 通过开闭运算,进行形态学处理
Mat element1 = getStructuringElement(MORPH_ELLIPSE,Size(15, 15)); //将硬币的内部凸显出来
morphologyEx(thresholdImage, thresholdImage, MORPH_CLOSE, element1);
Mat element2 = getStructuringElement(MORPH_RECT ,Size(5, 5)); //滤掉周围的小点
morphologyEx(thresholdImage, thresholdImage, MORPH_OPEN, element2);
imshow("filtered image", thresholdImage);
//【5】 找到轮廓并标出
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(thresholdImage, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));
RNG g_rng(999999);
for (int i = 0; i< contours.size() ; i++)
{
Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//任意值
drawContours(sourceImage, contours, i, color, 2, 8, hierarchy, 0, Point());
}
imshow("finished", sourceImage);
waitKey(0);
return;
}
结果截图:
阈值化后
形态学处理后
最后结果