Good day.

There are such pictures:

http://cdn.joxi.ru/uploads/prod/2014/09/12/42c/58d/6262f90e63c4b76fdeb27a6dd1d18b336663d92f.jpg

As you can see, black letters are depicted in black, but there are a lot of dead pixels on them.
We need an algorithm, how to reduce the number of dead pixels to a minimum by painting the letter in black.

  • 3
    Captcha bot doing?)) - Cooler
  • In general, the problem is very serious. If all the pictures are “about” such, it is worth taking some ready-made classifying neural network, train it to classify the letters by such pictures and so “recognize” the text. If we are talking about painting, then the algorithm will be very difficult, it is necessary to select clusters with a size limit from the top based on the picture, and then reverse their color (black to make white, white to black). - Arkady
  • Not sure, but you can try to first apply this [algorithm] [1] on the image, and after trying [the closure] [2], it will suddenly come out. [1]: en.wikipedia.org/wiki/Balanced_histogram_thresholding [2]: en.wikipedia.org/wiki/… - gcoder
  • What are the ready classifying neural network advise? - Alexander Adv

2 answers 2

You can try the Tan-Triggs algorithm. In OpenCV, I met its use to reduce the variability of light in face recognition, but in my task it, in my opinion, can help.

enter image description here enter image description here enter image description here

The characters are relatively clean, the areas of their styles are practically intact, which significantly reduces the complexity of further processing, which in the same OpenCV will be reduced to fairly simple operations.

The algorithm itself is quite fast and does not require any training:

Mat tan_triggs_preprocessing(InputArray src , float alpha = 0.1, float tau = 10.0, float gamma = 0.2 , int sigma0 = 1, int sigma1 = 2) { Mat X = src.getMat(); X.convertTo(X, CV_32FC1); Mat I; pow(X, gamma, I); // Calculate the DOG Image: { Mat gaussian0, gaussian1; // Kernel Size: int kernel_sz0 = (3*sigma0); int kernel_sz1 = (3*sigma1); // Make them odd for OpenCV: kernel_sz0 += ((kernel_sz0 % 2) == 0) ? 1 : 0; kernel_sz1 += ((kernel_sz1 % 2) == 0) ? 1 : 0; GaussianBlur(I, gaussian0, Size(kernel_sz0,kernel_sz0) , sigma0, sigma0, BORDER_CONSTANT); GaussianBlur(I, gaussian1, Size(kernel_sz1,kernel_sz1) , sigma1, sigma1, BORDER_CONSTANT); subtract(gaussian0, gaussian1, I); } { double meanI = 0.0; { Mat tmp; pow(abs(I), alpha, tmp); meanI = mean(tmp).val[0]; } I = I / pow(meanI, 1.0/alpha); } { double meanI = 0.0; { Mat tmp; pow(min(abs(I), tau), alpha, tmp); meanI = mean(tmp).val[0]; } I = I / pow(meanI, 1.0/alpha); } // Squash into the tanh: { for(int r = 0; r < I.rows; r++) { for(int c = 0; c < I.cols; c++) { I.at<float>(r,c) = tanh(I.at<float>(r,c) / tau); } } I = tau * I; } return I; } 

It’s easy to use:

 Mat src_mat = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE); Mat dst_mat = tan_triggs_preprocessing(src_mat); normalize(dst_mat, dst_mat, 0, 255, NORM_MINMAX, CV_8UC1); Mat res_mat = src_mat - dst_mat; imshow("TanTriggs Image", res_mat); 

    As already said - to classify immediately. Look for examples of classifiers for MNIST - a database of handwritten numbers. From this example, everyone begins to learn classifiers.

    Also try to binarize the image, for example, using the Otsu method

    Also try blur options, such as median filtering.