从图像中提取较小的图像
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(替代方案将为您完成一切。但是,如果您使用最简单的解决方案解决问题,它不会让您成为更好的程序员)
我开始学习 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(替代方案将为您完成一切。但是,如果您使用最简单的解决方案解决问题,它不会让您成为更好的程序员)