-3

在谷歌上没有找到答案,所以请求你的帮助:我需要自己制作识别 2D 的 C++ 程序!!!(密码)条形码(手工制作的代码)。它由 20-100 行组成。每一行 - 一个词。

决定使用 OpenCV。需要在图像组上查找条形图,从左上角裁剪和扫描图片。

裁剪和代码搜索没有问题。不明白,如何正确识别黑白像素线以获得每条线的唯一组合。

正如我所理解的,好方法 - 逐行查看白色像素或黑色,如果黑色 - 写 1,如果白色 = 0 .... 而不是像这样写序列:

11111111 000000 111111 00000000000 111111111111111 0000000 1111 = 8 6 6 11 15 7 4(计数 1 和 0 数量)= 得到 866111574 比使用系数取决于作物宽度和高度来找到一致。

如何使用 Opencv 在 C++ 代码中编写这个?不明白。尝试使用 cvInitLineIterator ...你有什么建议?谢谢你。

4

2 回答 2

1

你没有提供任何图像或代码片段,所以你现在不太清楚。
一些一般的想法:

1) 搜索您的代码角。

2)计算同应性。

3)应用单应变换来获得代码的方形图像。

4)您应该知道代码的行数(或行数),因此只需将图像划分为水平线。

5)获取每条线的投资回报率。计算沿垂直轴的像素总和 (cv::reduce)(以获得一些统计数据)。现在您有 1 条带有白色和黑色区域的水平线。

6) 将这条线分成 N 段(代码字长),然后计算每段的像素总和。

7)应用阈值,您将获得代码。

于 2013-08-27T06:48:43.197 回答
1

您可以像这样迭代槽像素:

uchar pixel = 0;
Mat img; // this must be grayscale image - type CV_8U
for(int i=0; i<img.rows; i++)
{
    // this loop is iterating from left to right
    for(int j=0; i<img.cols; j++)
    {
        pixel = img.at<uchar>(i,j);
        // do something (e.g. sum pixels)
        // OpenCV doesn't have binary image type, so usually white pixels value is 255
    }
}

更好的解决方案可能是使用findContoursminAreaRect,它们应该在每条线周围创建一个矩形:

vector<vector<Point>> vecContours;
vector<Vec4i> hierarchy;
RotatedRect currentRect; 

Mat binaryImage = imread(...)

// binaryImage should contain only shapes or edges, I suggest using one of these approaches:
// simple binary tresholding, try different threshold_value
threshold(binaryImage, binaryImage, threshold_value, 255, THRESH_BINARY);

// adaptiveTreshold works better when image is varying in brightness
// adjust blockSize and C (start with C=0)
adaptiveThreshold(binaryImage, binaryImage, 255, ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, blockSize, C);

// another option would be to use Canny edge detector: 
// http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html

// find external contours, binaryImage = grayscale 8-bit image
// binaryImage is modified during findContours so we create a clone
findContours(binaryImage.clone(), vecContours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

// find minAreaRect for each contour (each line)
for (size_t = 0; i < vecContours.size(); i++)
{   
    // filter unwanted objects (contours with less than 4 points, contours with too small area)
    if (vecContours[i].size() < 4 || contourArea(vecContours[i]) < someAreaInPixels)
        continue;

    // you can draw contours for debugging
    // drawContours(binaryImage, vecContours, i, Scalar(255,0,0), 1, 8, hierarchy, 0, Point());

    RotatedRect minRect = minAreaRect(vecContours.at(i));

    // now you can use minRect.size.width to determine width of the bar
    // minRect contains center point, size and angle
}
于 2013-08-27T07:03:46.470 回答