由于现在是我的学校假期,我决定选择一些技巧,因此我试图学习如何在Visual Studio C++中使用OpenCV功能来检测许多罐在纸箱,并不得不将其分组4 4。 使用Opencv和Hough变换圆圈来检测圆圈(下标错误)
我已经尝试了各种演示代码,如“opencv find:contour”,模板匹配(无法正常工作,因为它无法检测到旋转顶部盖子)
我发现的最佳方法是将Canny边缘检测和Hough变换圆组合起来,使得Canny边缘检测的输出结果可以是Hough变换圆的输入图像,结果如下。
不幸的是,当检测到不是所有的圈子,如果我改变
for (int i = 0; i < circles.size(); i++)
到
for (int i = 0; i < 24; i++) // 24 is the no. of cans
我会得到一个表达:向量下标超出范围。我不知道为什么它是唯一能够检测21圈
来源如下代码: -
using namespace cv;
using namespace std;
Mat src, src_gray;
int main()
{
Mat src1;
src1 = imread("cans.jpg", CV_LOAD_IMAGE_COLOR);
namedWindow("Original image", CV_WINDOW_AUTOSIZE);
imshow("Original image", src1);
Mat gray, edge, draw;
cvtColor(src1, gray, CV_BGR2GRAY);
Canny(gray, edge,50, 150, 3);
//50,150,3
edge.convertTo(draw, CV_8U);
namedWindow("Canny Edge", CV_WINDOW_AUTOSIZE);
imshow("Canny Edge", draw);
imwrite("output.jpg", draw);
waitKey(500);
/// Read the image
src = imread("output.jpg", 1);
Size size(932, 558);//the dst image size,e.g.100x100
resize(src, src, size);//resize image
/// Convert it to gray
cvtColor(src, src_gray, CV_BGR2GRAY);
/// Reduce the noise so we avoid false circle detection
GaussianBlur(src_gray, src_gray, Size(9, 9), 2, 2);
vector<Vec3f> circles;
/// Apply the Hough Transform to find the circles
HoughCircles(src_gray, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows/8,200, 100, 0, 0);
/// Draw the circles detected
for (int i = 0; i < circles.size(); i++)
{
printf("are you um?\n");
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
// circle center
circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
// circle outline
circle(src, center, radius, Scalar(255, 0, 255), 3, 8, 0);
}
// namedWindow("Hough Circle Transform Demo", CV_WINDOW_NORMAL);
imshow("Hough Circle Transform Demo", src);
line(src, Point(0, 288), Point(1024, 288), Scalar(225, 220, 225), 2, 8);
// middle line
line(src, Point(360, 0), Point(360, 576), Scalar(225, 220, 225), 2, 8);
//break cans into 4 by 4
line(src, Point(600, 0), Point(600, 576), Scalar(225, 220, 225), 2, 8);
// x, y
imshow("Lines", src);
imwrite("lineoutput.jpg", src);
waitKey(0);
return 0;
}
我还手工打出来的坐标为线,以它们分成4×4 为了避免下标超出范围并且能够检测到所有圈子,我应该更改哪些内容?
你不能访问超过你找到的东西。它创建了21个圆圈,所以矢量包含21个圆圈。如果将循环变量更改为24,则会得到下标错误,导致向量大小为21.您无法访问其大小。要找到缺少的圈子,您可以添加程序中的圈子。它不会总是有效,但在某种程度上它会起作用。它像一个6x4的网格。从中心的距离,你可以很容易地假设哪些圈丢失..... –
我不认为我会手动添加圆圈,因为我有10多个不同的照明和位置的图像。 谢谢!修正了下标错误,我的6x4网格可能只是为了显示,因为它什么都不做:l – Lyber