Extract from image an smaller image

134 views Asked by At

I am starting learning an openCV and a have question about it.

My target is to recognize captcha.
First I must preprocess an image.

There is an example of captcha here

So problem is how to crop symbols from image and put it into 2D array(bitmap).

1

There are 1 answers

2
Imobilis On BEST ANSWER

Automatic Partition Detection


The first thing you'd need to do is create the filter array of background colors. This will be the array containing the colors that occur in the background. For that purpose you can just take the offset 20x20 area or leave it as a user option depending on your project standpoint.

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;
}

Well it didn't go that much pseudo-code.


Now that you have the filter you can limit outer pixels. Now what you need is a vertical raster scan. Or just vertical scan. Over the entire captcha image. Each pixel of the vertical line will be additionally checked if it matches some color from the already-obtained area. If all the pixels of the line (that has the size of the image's height) return positive when checked whether pixel is close to or matches area color, an aray indexer will increment so that we have where the last character ends. enter image description here


Edit 1 For 3 seconds I GIMPed the color curves of the image, resulting in a plain background: enter image description here

So this respectively simplifies the filtering process quite a lot. The color curves magic I did is actually only a brightness/contrast adjustment control, which is maybe the easiest color processing you can implement (after the invert).


I might periodically edit to clarify some more. This will certainly give you a good practice. A real practice.

Doc:

  • BMP File Format (More than enough information for you to start working with bitmaps. The most important one is the bitmap structure, which is a combination of BMPINFOHEADER and DIBHEADER).
  • Tesseract OCR (alternative that will do everything for you. However if you solve your problems with the easiest solution, it will not make you a better programmer)