Chinese Chess recognition

来源:互联网 发布:js new一个函数的过程 编辑:程序博客网 时间:2024/06/05 19:53

// this article's background as follows:

- Original Matlab code was from internet(author: Yangyang Yu)

- Translate Matlab code into C++ code with OpenCV;

- Increase programming ability;


Algorithm:

- Segmentation

- Find coners


Code:

#include"opencv2\highgui\highgui.hpp"
#include"opencv2\core\core.hpp"
#include"opencv2\imgproc\imgproc.hpp"
#include<iostream>
#include<math.h>


using namespace cv;
using namespace std;


cv::Mat im_board_orig_color, im_board_golden_color, im_board_golden, im_board_orig, board_mask;  //gloden sample for chess board(no chess pieces);
                                                                                           //sampling pictures 
                                                                                           //segmentation of chess board(board);
void transform_board(Mat im_color, Mat im_board_golden);
Mat generate_board_mask(Mat im_board);
void find_homography_transformation(Mat board_mask);
void find_corners(Mat picture_edges);


int main() {

//load sampling picture
im_board_orig_color = cv::imread("D:/digital image process/Yu/Chinese_Chess_State_Recognition_Code/Database/view_5.jpg");
if (!im_board_orig_color.data) {
cout << "can not open im_board_orig_color pic!";
return 0;
}


//load golden sample  
im_board_golden_color = cv::imread("D:/digital image process/Yu/Chinese_Chess_State_Recognition_Code/board_empty_golden.jpg");
if (!im_board_golden_color.data) {
cout << "can not open im_board_golden_color pic!";
return 0;
}


//segmentation of chess board; affine transformation
cv::cvtColor(im_board_golden_color, im_board_golden, CV_BGR2GRAY);
transform_board(im_board_orig_color, im_board_golden);
return 1;
}


void transform_board(Mat im_color, Mat im_board_golden) {
//padding array:top,down,left,right; i do not know why need to padding
int height = im_color.rows; int width = im_color.cols;
cv::copyMakeBorder(im_color, im_board_orig_color, max(height, width) - height, max(height, width) - height, max(height, width) - width, max(height, width) - width, cv::BORDER_CONSTANT, cv::Scalar(0));
cv::cvtColor(im_board_orig_color, im_board_orig, CV_RGB2GRAY);


//chess board segmentation
cv::Mat mask=generate_board_mask(im_board_orig);
cv::bitwise_and(mask, im_board_orig, board_mask);


//affine transformation
find_homography_transformation(board_mask);
}


Mat generate_board_mask(Mat im_board) {
Mat im_board_only_bw, im_thresh,im_board_only_bw_inv;


//binaryzation by OTSU
double thresh = cv::threshold(im_board, im_board_only_bw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
threshold(im_board, im_board_only_bw, thresh, 255, THRESH_BINARY);
im_thresh = im_board_only_bw.clone();


//matlab imfill(bw,'holes')
floodFill(im_board_only_bw, cv::Point(0, 0), Scalar(255));   
bitwise_not(im_board_only_bw, im_board_only_bw_inv);
im_board_only_bw = (im_thresh | im_board_only_bw_inv);


//morphology operation,size refer to matlab program
Mat element = getStructuringElement(MORPH_ELLIPSE, Size(3, 3), Point(-1, -1));
erode(im_board_only_bw, im_board_only_bw, element, Point(-1, -1), 1);


//A:removing small blobs which similar to matlab's bwareaopen vs findContours
vector<vector<Point>> contours;
contours.resize(100);
vector<Vec4i> hierarchy;
Mat im_contours = im_board_only_bw.clone();
findContours(im_contours, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));


    //A1:get max area to calculate the thresh later:max*0.5 
double area_thr = 0;
double area_contour[300];
for (int i = 0; i < contours.size(); ++i){
area_contour[i] = contourArea(contours[i]);
if (contourArea(contours[i])>area_thr) area_thr = contourArea(contours[i]);
}


//A2: removing...
for (int i = 0; i < contours.size(); ++i){
double area = contourArea(contours[i]);
if (area < area_thr*0.5){
drawContours(im_board_only_bw, contours, i, CV_RGB(0,0,0), -1);
}
}


//morphology operation,size refer to matlab program
Mat element_big = getStructuringElement(MORPH_ELLIPSE, Size(13, 13), Point(-1, -1));
//erode(im_board_only_bw, im_board_only_bw, element);
dilate(im_board_only_bw, im_board_only_bw, element,Point(-1,-1),1);
dilate(im_board_only_bw, im_board_only_bw, element_big, Point(-1, -1), 1);

//matlab imfill(bw,'holes')
Mat im_fill = im_board_only_bw.clone(); 
Mat im_fill_inv;
floodFill(im_fill, cv::Point(0, 0), Scalar(255));


bitwise_not(im_fill, im_fill_inv);
im_board_only_bw = (im_board_only_bw | im_fill_inv);


Mat temp = im_board_only_bw.clone();
findContours(temp, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
//B1:get max area to calculate the thresh later:max*0.5 
  area_thr = 0;
//double area_contour[300];
for (int i = 0; i < contours.size(); ++i){
area_contour[i] = contourArea(contours[i]);
if (contourArea(contours[i])>area_thr) area_thr = contourArea(contours[i]);
}


//B2: removing...
for (int i = 0; i < contours.size(); ++i){
double area = contourArea(contours[i]);
if (area < area_thr*0.5){
drawContours(im_board_only_bw, contours, i, CV_RGB(0, 0, 0), -1);
}
}


return im_board_only_bw;
}


void find_homography_transformation(Mat board_mask){
find_corners(board_mask);
}


void find_corners(Mat picture_edges){




}

Chinese Chess State Recognition
0 0