如何使用OpenCV在此圖像中檢測中國象棋棋子?
我嘗試過使用HoughCircles,但沒有找到圓圈.
Mat src = imread( "x.jpg", CV_LOAD_IMAGE_GRAYSCALE);
GaussianBlur( src, src, Size(9, 9), 2, 2 );
vector circles;
HoughCircles( src, circles, CV_HOUGH_GRADIENT, 1, src.rows/16);
cout << circles.size() << endl;
// The output is: 0
還測試了斑點檢測器,但結果不正确.
Mat im = imread( "x.jpg", IMREAD_GRAYSCALE );
vector kps;
SimpleBlobDetector().detect(im, kps);
Mat im_kps;
drawKeypoints( im, kps, im_kps, Scalar(0,0,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS );
imshow("keypoints", im_kps );
waitKey(0);
解決方法:
當從圖像m中隔離紅色時可能出現的一個問題是棋子與紅色背景的混合.在運作inRange()時,會發生這種情況:
乍看之下判斷跳棋的位置真是太難了!但是我們可以使用技巧克隆擴張和侵蝕來移除次要部分(網格),同時保留重要部分(圓形檢查器).
這是解決檢查問題的擴張和侵蝕的代碼:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include
using namespace cv;
using namespace std;
Mat getElement(int erosion_size)
{
return getStructuringElement(cv::MORPH_ELLIPSE,
cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1),
cv::Point(erosion_size, erosion_size) );
}
int main( )
{
vector > contours;
//vector hierarchy;
//int largest_area,largest_contour,largest_contour_index;
//RotatedRect bounding_ellipse;
Mat image,dst,filtered;
Mat a1,a2;
//Color ranging red (from both left & right spectrums)
image = imread("circles.jpg");
cvtColor(image,filtered,CV_BGR2HSV);
Scalar low = Scalar(0, 100, 50);
Scalar up = Scalar(10, 255, 255);
Scalar low2 = Scalar(160, 100, 50);
Scalar up2 = Scalar(179, 255, 255);
inRange(filtered, low2, up2, a1);
inRange(filtered, low2, up2, a2);
bitwise_or(a1,a2,filtered);
imshow("troll", filtered);
// Fill in small holes from Chinese lettering
dilate(filtered,filtered,getElement(11));
imshow("better", filtered);
// Erode to remove minor (like square lines) objects
erode(filtered,filtered,getElement(25));
imshow("best",filtered);
findContours(filtered, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
for( int i = 0; i< contours.size(); i++ )
{
//Only draw big contours, not minor details
double area =contourArea( contours[i],false);
if(area > 1500)
{
drawContours(image, contours, i, Scalar(0,255,0), 5);
}
}
imshow( "Result window", image );
waitKey(0);
return 0;
}
說明:
1.擴張
我們從膨脹開始,它允許圖像的較亮部分“擴充”在“較暗”部分上.是以,在這裡,我們将使用它來删除中文字母(是以,在擴張時,我們将不會在圓圈中間有大洞):
2.侵蝕
如你所見,現在圓圈已經填滿,我們可以繼續進行侵蝕.我們需要擴張超過我們侵蝕的量,因為我們需要從圖像中移除網格條.應用侵蝕,我們隻得到棋盤上的棋子(以及我們稍後會處理的一些噪音):
3.輪廓處理
現在,我們可以處理檢查器,但我們需要濾除圖像周圍的噪音.為此,我們将從侵蝕結果中運作findContours(),但我們還将檢查輪廓的contourArea()區域,以確定它是我們的檢查器.如果面積小于1500,我們知道它是噪音,我們可以把它丢棄.否則,我們可以将它繪制到螢幕上.
标簽:c,opencv,detection
來源: https://codeday.me/bug/20190829/1761402.html