2

I'm new to OpenCV and image processing and I'M not sure how to solve my problem. I have a photo of document made in iPhone and I want to convert that document to black and white. I tried to use threshold but the text was not so good (a little blurry and unreadable). I'd like to text looks same as on the original image, only black, and background will be white. What can I do? P.S. When I made a photo of part of the document, where text is quite big, then result is ok.

I will be grateful for any help.

Here are the example image I use and the result: enter image description here enter image description here

karlphillip
  • 92,053
  • 36
  • 243
  • 426
Bartosz Bialecki
  • 4,391
  • 10
  • 42
  • 64

3 Answers3

1

My attemp, maybe a little more readable than yours:

IplImage * pRGBImg  = 0;
pRGBImg = cvLoadImage(input_file.c_str(), CV_LOAD_IMAGE_UNCHANGED);
if(!pRGBImg)
{   
    std::cout << "ERROR: Failed to load input image" << std::endl;
    return -1; 
}   

// Allocate the grayscale image
IplImage * pGrayImg = 0;
pGrayImg = cvCreateImage(cvSize(pRGBImg->width, pRGBImg->height), pRGBImg->depth, 1); 

// Convert it to grayscale
cvCvtColor(pRGBImg, pGrayImg, CV_RGB2GRAY);

// Dilate
cvDilate(pGrayImg, pGrayImg, 0, 0.2);

cvThreshold(pGrayImg, pGrayImg, 30, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
cvSmooth(pGrayImg, pGrayImg, CV_BLUR, 2, 2);

cvSaveImage("out.png", pGrayImg);

enter image description here

karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • Thank for your reply. It is a little bit better but not super. Isn't there a possibility only to remove a background without changing a text? I'm afraid I cannot do to much because the resolution of that image is only 720x960px and quality is not so good. – Bartosz Bialecki Jul 07 '11 at 15:12
  • You can write an algorithm for that. Iterate over the pixels of the grayscaled image replacing the pixels that correspond to the background color (or pixels near that specific color) with white pixels. – karlphillip Jul 07 '11 at 19:14
  • How can I find that background color? I tried with that: for (int i = 0; i<100;i++) { for (int j = 0; jwidth;j++) { int u = (unsigned char)img->imageData[i*img->width+j]; sum += u; count++; } } int gray = sum / count; But the result is not good. – Bartosz Bialecki Jul 08 '11 at 07:25
0

Using Adaptive Gaussian Thresholding is a good idea here. This will also enhance the quality of text written in the image. You can do that by simply giving the command:

AdaptiveThreshold(src_Mat, dst_Mat, Max_value, Adaptive_Thresholding_Method, Thresholding_type, blocksize, C);
Mogo
  • 11
  • 3
0

Threshold image is used for different purposes.

If u just want to convert it to b/w image just do this. USing openCV 2.2

cv::Mat image_name = cv::imread("fileName", 0);

the second parameter 0 tells to read a color image as b/w image.

And if you want to save as a b/w image file.

code this

cv::Mat image_name = cv::imread("fileName", 0);
cv::imwrite(image_name, "bw_filename.jpg");
Nick
  • 1,692
  • 3
  • 21
  • 35