OpenCV找到近距离物体的轮廓

时间:2015-03-11 08:57:38

标签: c++ opencv computer-vision

我正在使用OpenCV库编写C ++应用程序来检测图像中的对象。这些图像看起来像这样: http://fs1.directupload.net/images/150311/my6uczfn.png 图像的上半部分是黑色的,可以忽略不计。

我知道,每个不属于所需物体的像素都会以白色着色。我想要做的是找出图像上有多少感兴趣的对象以及它们在哪里。 到目前为止,我编写了以下代码:

Mat image = imread("2.png", CV_LOAD_IMAGE_COLOR);
if(!image.data)
{
  std::cout << "Could not open or find the image." << std::endl;
}

Range range_rows(0, image.size().height);
Range range_columns_left(0, image.size().width);
Range range_columns_middle(image.size().width, image.size().width * 2);
Range range_columns_right(image.size().width * 2, image.size().width * 3);
Mat display_mat(image.size().height, image.size().width * 3, CV_8UC3);
Mat left(display_mat, range_rows, range_columns_left);
image.copyTo(left);

Mat classified_image;
threshold(image, classified_image, 254, 255, THRESH_BINARY);
Mat middle(display_mat, range_rows, range_columns_middle);
classified_image.copyTo(middle);

Mat cimage = Mat::zeros(image.size(), CV_8UC3);

Mat classified_grayscale_image;
cvtColor(classified_image, classified_grayscale_image, CV_RGB2GRAY); 
std::vector< std::vector<cv::Point> > contours;
findContours(classified_grayscale_image, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);

for(size_t counter = 0; counter < contours.size(); counter++)
{
  std::cout << "Contours size: " << contours[counter].size() << std::endl;
  if(contours[counter].size() < 6)
    continue;

  Mat pointsf;
  Mat(contours[counter]).convertTo(pointsf, CV_32F);
  RotatedRect box = fitEllipse(pointsf);

  drawContours(cimage, contours, (int)counter, Scalar::all(255), 1, 8);
  ellipse(cimage, box, Scalar(0,0,255), 1, CV_AA);
  std::cout << "Ellipse Parameter:\t";
  ellipse(cimage, box.center, box.size*0.5f, box.angle, 0, 360, Scalar(0,255,255), 1, CV_AA);
  Point2f vtx[4];
  box.points(vtx);
  for( int j = 0; j < 4; j++ )
      line(cimage, vtx[j], vtx[(j+1)%4], Scalar(0,255,0), 1, CV_AA);
}

Mat right(display_mat, range_rows, range_columns_right);
cimage.copyTo(right);

namedWindow("Results", CV_WINDOW_AUTOSIZE);
imshow("Results", display_mat);

waitKey(0);

return 0;

结果如下: http://fs1.directupload.net/images/150311/toiy3aes.png

如您所见,分类,什么是对象,什么不是,并不完美,因此2个对象被识别为一个。分类将得到改进,但如果这些对象非常接近,可能会发生类似的情况。更重要的是,当他们互相接触时。 如何在上面显示的情况下进行正确的物体识别?有什么想法吗?

1 个答案:

答案 0 :(得分:0)

你有几个选择:

  • 对结果图像使用一些过滤/阈值处理方法,以便彼此分割对象。在这种情况下,Otsu二值化应该足够了,或者你可以尝试使用扩张操作。
  • 反转你的结果图像,而不是使用距离变换和Otsu二值化(或其他类型的阈值处理 - 大多数应该可以正常工作)。它会让你的物体更小,但会更容易计算它们。
  • 如果您需要尽可能精确地标记对象,则需要使用更复杂的方法。 Here有一个教程,它使用我上面描述的技术和连接的组件和分水岭。