天天看點

matlab識别中國象棋棋盤,c – 使用OpenCV在棋盤中檢測中國象棋棋子

如何使用OpenCV在此圖像中檢測中國象棋棋子?

matlab識别中國象棋棋盤,c – 使用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()時,會發生這種情況:

matlab識别中國象棋棋盤,c – 使用OpenCV在棋盤中檢測中國象棋棋子

乍看之下判斷跳棋的位置真是太難了!但是我們可以使用技巧克隆擴張和侵蝕來移除次要部分(網格),同時保留重要部分(圓形檢查器).

這是解決檢查問題的擴張和侵蝕的代碼:

#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.擴張

我們從膨脹開始,它允許圖像的較亮部分“擴充”在“較暗”部分上.是以,在這裡,我們将使用它來删除中文字母(是以,在擴張時,我們将不會在圓圈中間有大洞):

matlab識别中國象棋棋盤,c – 使用OpenCV在棋盤中檢測中國象棋棋子

2.侵蝕

如你所見,現在圓圈已經填滿,我們可以繼續進行侵蝕.我們需要擴張超過我們侵蝕的量,因為我們需要從圖像中移除網格條.應用侵蝕,我們隻得到棋盤上的棋子(以及我們稍後會處理的一些噪音):

matlab識别中國象棋棋盤,c – 使用OpenCV在棋盤中檢測中國象棋棋子

3.輪廓處理

現在,我們可以處理檢查器,但我們需要濾除圖像周圍的噪音.為此,我們将從侵蝕結果中運作findContours(),但我們還将檢查輪廓的contourArea()區域,以確定它是我們的檢查器.如果面積小于1500,我們知道它是噪音,我們可以把它丢棄.否則,我們可以将它繪制到螢幕上.

matlab識别中國象棋棋盤,c – 使用OpenCV在棋盤中檢測中國象棋棋子

标簽:c,opencv,detection

來源: https://codeday.me/bug/20190829/1761402.html