从图像中提取较小的图像

Extract from image an smaller image

我开始学习 openCV 并且对此有疑问。

我的目标是识别验证码。
首先我必须预处理图像。

有验证码的例子 here

所以问题是如何从图像中裁剪符号并将其放入二维数组(位图)中。

自动分区检测


您需要做的第一件事是创建背景颜色过滤器数组。这将是包含出现在背景中的颜色的数组。为此,您可以只采用偏移 20x20 区域或将其保留为用户选项,具体取决于您的项目立场。

typedef unsigned char Pixel [3];
typedef *Pixel PixelArray;

// Function to return offset byte of x/y coordinate
int bmp_get_offset (int width, int x, int y)
{
    int w = width;
    const int channels = 3;
    const int bpp = 8;
    const int single = (channels * bmpp) / 8;
    const int offset = 54;
    int rowsize = w * single;
    int pixAddress;

    if(rowsize % 4 != 0) rowsize += 4 - (rowsize % 4);
    pixAddress = offset + yp * rowsize + xp * single;

    return pixAddress;
}

// Function to return specific area (pseudo-code)
PixelArray bmp_get_area (FILE * bmp, int x, int y, int w, int h)
{
    PixelArray buffer = buffer_new(bmp); // sets image into a memory-allocated buffer
    PixelArray area [h * w];
    const int src_width  = *((int*)&buffer[(0x12)]);

    for(int iWidth = 0; iWidth < w; iWidth++)
        for(int iHeight = 0; iHeight < h; iHeight++)
            area[iHeight * src_width + iWidth] = buffer[bmp_get_offset(src_width, x + iWidth, y + iHeight)];

    return area;
}

好吧,它并没有那么多伪代码。


现在您有了过滤器,您可以限制外部像素。 现在您需要的是垂直光栅扫描。或者只是垂直扫描。 在整个验证码图像上。 如果垂直线的每个像素与已经获得的 area 中的某些颜色相匹配,则会额外检查它。 如果在检查像素是否接近或匹配 area 颜色时,该行的所有像素(具有图像高度的大小)return 为正,则数组索引器将递增,以便我们得到最后一个字符结束。


编辑 1 在 3 秒内,我对图像的颜色曲线进行了 GIMP,得到了一个纯色背景:

所以这分别大大简化了过滤过程。 我做的颜色曲线魔术实际上只是一个 brightness/contrast 调整控件,这可能是您可以实现的最简单的颜色处理(在反转之后)。


我可能会定期编辑以澄清更多内容。这肯定会给你一个很好的练习。真正的实践。

文档:

  • BMP File Format(足以让您开始使用位图。最重要的是位图结构,它是 BMPINFOHEADER 和 DIBHEADER 的组合)。
  • Tesseract OCR(替代方案将为您完成一切。但是,如果您使用最简单的解决方案解决问题,它不会让您成为更好的程序员)