擊中擊不中屬於圖像形態學操作範疇,通過定義一定形狀的結構元素,然後在圖像中尋找與該結構元素相同的區域,找到即爲擊中,找不到即爲擊不中。
代碼如下
#include<iostream>
#include<opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
//加載圖像
Mat src = imread("1.png");
if (src.empty())
{
cout << "no image!" << endl;
return -1;
}
imshow("src", src);
//灰度處理
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
imshow("gray", gray);
//高斯濾波
Mat gauss;
GaussianBlur(gray, gauss, Size(5, 5), 0, 0);
imshow("gauss", gauss);
//二值化
Mat binary;
threshold(gauss, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
imshow("binary", binary);
//擊中操作
Mat hitImg;
Mat kern = getStructuringElement(MORPH_CROSS, Size(11, 11));
morphologyEx(binary, hitImg, MORPH_HITMISS, kern);
imshow("hitMiss", hitImg);
//膨脹一下
Mat openImg;
Mat kern2 = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(hitImg, openImg, MORPH_OPEN, kern2,Point(-1,-1),2);
imshow("dilate", openImg);
//尋找輪廓
vector<vector<Point>>contours;
vector<Vec4i>hie;
Mat mask = Mat::zeros(src.size(), CV_8UC3);
findContours(openImg, contours, hie, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
for (size_t i = 0; i < contours.size(); i++)
{
double area = contourArea(contours[i]);
if (area < 20.0)continue;
Rect rect = boundingRect(contours[i]);
drawContours(mask, contours, static_cast<int>(i), Scalar(255, 255, 255), -1, 8);
rectangle(src, rect, Scalar(0, 0, 255), 1, 8);
cout << "面積:" << area << endl;
}
imshow("mask", mask);
imshow("srcImg", src);
Mat result;
bitwise_and(src, mask, result);
imshow("result", result);
waitKey(0);
return 0;
}
原圖
結果
關於圖像形態學操作,選擇合適的操作方法很重要,但是定義一個合適的結構元素也很關鍵。
而常用的一些結構元素有3*3,5*5,7*7,或者一些矩形的結構元素,image.cols*1,1*image.rows等等。