findChessboardCorners求出的Corners按确定顺序排列

目的:

在做平面机械臂(三轴台、SCARA)的手眼标定时,尝试使用棋盘格标定板来实现九点标定,要求每次求出的Corners都按相同的排列顺序,但是bool cv::findChessboardCorners函数求出的Corners排列顺序并不确定,只能对Corners的顺序进行重排

说明:

opencv中findChessboardCorners函数是用来检测棋盘格Corners的函数,官方函数说明如下:

bool cv::findChessboardCorners ( InputArray  image,
    Size  patternSize,
    OutputArray  corners,
    int  flags = CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE 
  )  

 

Finds the positions of internal corners of the chessboard.

Parameters

image Source chessboard view. It must be an 8-bit grayscale or color image.
patternSize Number of inner corners per a chessboard row and column ( patternSize = cvSize(points_per_row,points_per_colum) = cvSize(columns,rows) ).
corners Output array of detected corners.
flags Various operation flags that can be zero or a combination of the following values:
  • CV_CALIB_CB_ADAPTIVE_THRESH Use adaptive thresholding to convert the image to black and white, rather than a fixed threshold level (computed from the average image brightness).
  • CV_CALIB_CB_NORMALIZE_IMAGE Normalize the image gamma with equalizeHist before applying fixed or adaptive thresholding.
  • CV_CALIB_CB_FILTER_QUADS Use additional criteria (like contour area, perimeter, square-like shape) to filter out false quads extracted at the contour retrieval stage.
  • CALIB_CB_FAST_CHECK Run a fast check on the image that looks for chessboard corners, and shortcut the call if none is found. This can drastically speed up the call in the degenerate condition when no chessboard is observed.

The function attempts to determine whether the input image is a view of the chessboard pattern and locate the internal chessboard corners. The function returns a non-zero value if all of the corners are found and they are placed in a certain order (row by row, left to right in every row). Otherwise, if the function fails to find all the corners or reorder them, it returns 0. For example, a regular chessboard has 8 x 8 squares and 7 x 7 internal corners, that is, points where the black squares touch each other. The detected coordinates are approximate, and to determine their positions more accurately, the function calls cornerSubPix. You also may use the function cornerSubPix with different parameters if returned coordinates are not accurate enough.

 

画出结果:

 

按文档说明,求出的 corners应该是按从左到右,从上到下的顺序,一行一行排列的,但本人使用过程中,发现有时从左上角开始排列,有时却是从右下角开始,似乎没办法确定顺序,固添加如下代码,来确保corners从左上角开始排列:

   
int findcorners( const cv::Mat& ChessImage, cv::Mat& viewImage,  const cv::Size& patternsize)
{
   cv::Mat ImageGray;
   if(ChessImage.empty())
   {
       std::cout << "ChessImage Empty" << std::endl;
       return 4;
   }

   //去畸变
//   bool hasDistortion = true;
//   cv::Mat undistortImage;
//   if(hasDistortion)
//   {
//       cv::undistort(ChessImage, undistortImage, camMatrix, distCoefs);
//   }

   std::vector ChessPoint;
   if(0 == cv::findChessboardCorners(ChessImage,patternsize,ChessPoint,cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE
                                     + cv::CALIB_CB_FAST_CHECK))
   {
       cout<<"can not find chessboard corners!\n"; //找不到角点
       return false;
   }

   if(ChessImage.channels() == 3)
   {
       cv::cvtColor(ChessImage, ImageGray, CV_RGB2GRAY);
   }
   else
   {
       ChessImage.copyTo(ImageGray);
   }

   cv::find4QuadCornerSubpix(ImageGray, ChessPoint, cv::Size(5,5));

   //确保角点从上往下,从左往右排列
   if(ChessPoint[0].x > ChessPoint.back().x)
   {
       //交换列
       for(int i=0; i < (int)patternsize.height; i++)  //行
           for(int j=0; j < (int)patternsize.width/2; j++) //列
               std::swap(ChessPoint[i*patternsize.width + j], ChessPoint[(i + 1)*patternsize.width - j - 1]);
   }
   if(ChessPoint[0].y > ChessPoint.back().y)
   {
       //交换行
       for(int i=0; i < (int)patternsize.width; i++) //列
           for(int j=0; j < (int)patternsize.height/2; j++) //行
               std::swap(ChessPoint[j*patternsize.width + i], ChessPoint[(patternsize.height - j - 1)*patternsize.width + i]);
   }

   cv::drawChessboardCorners(viewImage, patternsize, ChessPoint, true);
   return true;
}

 

你可能感兴趣的:(图像)