0

the scenario goes like this, i have an image which i want to extract text only from it for further OCR processing, i have tried to remove logos by erosion and dilation but it fails when the card have an image in it's background or the card is split into 2 different colors, so i think to calculate the histogram of the card and then filter the text as it will have the least peak among the background or any other non text area i get this opencv code to calculate the histogram of the image

OpenCV Code:

IplImage* trueColorImage = cvLoadImage("plastics.jpg");
TrueColorIplImg=[self CreateIplImageFromUIImage:trueColorImage];
IplImage* channel = cvCreateImage( cvGetSize(TrueColorIplImg), 8, 1);
IplImage *hist_img = cvCreateImage(cvSize(300,240), 8, 1);
cvSet( hist_img, cvScalarAll(255), 0 );
CvHistogram *hist_red;
CvHistogram *hist_green;
CvHistogram *hist_blue;
int hist_size = 256;      
float range[]={0,256};
float* ranges[] = { range };
float max_value = 0.0;
float max = 0.0;
float w_scale = 0.0;
hist_red = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
hist_green = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
hist_blue = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
cvSetImageCOI(TrueColorIplImg,3);
cvCopy(TrueColorIplImg,channel);
cvResetImageROI(TrueColorIplImg);
cvCalcHist( &channel, hist_red, 0, NULL );
cvSetImageCOI(TrueColorIplImg,2);
cvCopy(TrueColorIplImg,channel);
cvResetImageROI(TrueColorIplImg);
cvCalcHist( &channel, hist_green, 0, NULL );
cvSetImageCOI(TrueColorIplImg,1);
cvCopy(TrueColorIplImg,channel);
cvResetImageROI(TrueColorIplImg);
cvCalcHist( &channel, hist_blue, 0, NULL );
cvGetMinMaxHistValue( hist_red, 0, &max_value, 0, 0 );
cvGetMinMaxHistValue( hist_green, 0, &max, 0, 0 );
max_value = (max > max_value) ? max : max_value;
cvGetMinMaxHistValue( hist_blue, 0, &max, 0, 0 );
max_value = (max > max_value) ? max : max_value;    
cvScale( hist_red->bins, hist_red->bins, ((float)hist_img->height)/max_value, 0 );
cvScale( hist_green->bins, hist_green->bins, ((float)hist_img->height)/max_value, 0 );
cvScale( hist_blue->bins, hist_blue->bins, ((float)hist_img->height)/max_value, 0 );
printf("Scale: %4.2f pixels per 100 units\n", max_value*100/((float)hist_img->height));                         
w_scale = ((float)hist_img->width)/hist_size;
 for( int i = 0; i < hist_size; i++ )
{
    cvRectangle( hist_img, cvPoint((int)i*w_scale , hist_img->height),
                cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_red->bins,i))),
                CV_RGB(255,0,0), -1, 8, 0 );
    cvRectangle( hist_img, cvPoint((int)i*w_scale , hist_img->height),
                cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_green->bins,i))),
                CV_RGB(0,255,0), -1, 8, 0 );
    cvRectangle( hist_img, cvPoint((int)i*w_scale , hist_img->height),
                cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_blue->bins,i))),
                CV_RGB(0,0,255), -1, 8, 0 );
}
karlphillip
  • 92,053
  • 36
  • 243
  • 426
chostDevil
  • 1,041
  • 5
  • 17
  • 24

1 Answers1

4

Generating the histogram is easy part and there's code available in the documentation of OpenCV. So you are not really giving us anything useful. The rest of the task is where the true challenge is. I would love to see your attempt dealing with that.

I noticed from your other questions that you are very interested in this problem. I need to say that solving it might be a little more complex than you previsouly imagined. You might want to restrict the scope of what you are trying to solve a little because developing a generic detection system for all types of business cards is going to be tough!

I've done some research and I'm going to share with you some of the interesting materials I've found:

Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426