OpenCV Adaptive Threshold OCR
Ich bin mit OpenCV zum vorbereiten von Bildern für die OCR-Funktion aus der iPhone-Kamera, und ich habe Schwierigkeiten die Ergebnisse brauche ich für eine präzise OCR-scan. Hier ist der code, den ich nun benutze.
cv::cvtColor(cvImage, cvImage, CV_BGR2GRAY);
cv::medianBlur(cvImage, cvImage, 0);
cv::adaptiveThreshold(cvImage, cvImage, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 5, 4);
Dieser Methode dauert ein bisschen zu lange und nicht mir gute Ergebnisse.
Irgendwelche Vorschläge, wie ich dies machen könnte Sie effektiver? Die Bilder stammen von einem iPhone-Kamera.
Nach der Verwendung von Andry ' s Vorschlag.
cv::Mat cvImage = [self cvMatFromUIImage:image];
cv::Mat res;
cv::cvtColor(cvImage, cvImage, CV_RGB2GRAY);
cvImage.convertTo(cvImage,CV_32FC1,1.0/255.0);
CalcBlockMeanVariance(cvImage,res);
res=1.0-res;
res=cvImage+res;
cv::threshold(res,res, 0.85, 1, cv::THRESH_BINARY);
cv::resize(res, res, cv::Size(res.cols/2,res.rows/2));
image = [self UIImageFromCVMat:cvImage];
Methode:
void CalcBlockMeanVariance(cv::Mat Img,cv::Mat Res,float blockSide=21) //blockSide - the parameter (set greater for larger font on image)
{
cv::Mat I;
Img.convertTo(I,CV_32FC1);
Res=cv::Mat::zeros(Img.rows/blockSide,Img.cols/blockSide,CV_32FC1);
cv::Mat inpaintmask;
cv::Mat patch;
cv::Mat smallImg;
cv::Scalar m,s;
for(int i=0;i<Img.rows-blockSide;i+=blockSide)
{
for (int j=0;j<Img.cols-blockSide;j+=blockSide)
{
patch=I(cv::Rect(j,i,blockSide,blockSide));
cv::meanStdDev(patch,m,s);
if(s[0]>0.01) //Thresholding parameter (set smaller for lower contrast image)
{
Res.at<float>(i/blockSide,j/blockSide)=m[0];
}else
{
Res.at<float>(i/blockSide,j/blockSide)=0;
}
}
}
cv::resize(I,smallImg,Res.size());
cv::threshold(Res,inpaintmask,0.02,1.0,cv::THRESH_BINARY);
cv::Mat inpainted;
smallImg.convertTo(smallImg,CV_8UC1,255);
inpaintmask.convertTo(inpaintmask,CV_8UC1);
inpaint(smallImg, inpaintmask, inpainted, 5, cv::INPAINT_TELEA);
cv::resize(inpainted,Res,Img.size());
Res.convertTo(Res,CV_32FC1,1.0/255.0);
}
Keine Ahnung warum erhalte ich dieses Ergebnis? Die OCR-Ergebnisse sind ziemlich gut, wäre aber besser, wenn ich bekommen konnte, um ein Bild ähnlich wie die, die Sie bekam. Ich entwickle für iOS, falls jene Gegenstände. Ich musste cvtColor
weil die Methode erwartet ein einkanaliges Bild.
- Nicht, dass Dritte param radius der convolution Maske? Muss ungerade sein, und nicht null.
- Ja, du hast Recht, lassen Sie mich gehen check-out, was der Standard ist, und versuchen, die. EDIT: habe Versucht ein paar und kaum verändert die Ergebnisse, was sonst?
- ändern blocksize-parameter die adaptive Schwelle zu höheren Werten, wie 25 usw.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist mein Ergebnis:
Hier ist der code:
patch=I(NSMakeRange(i,i+blockSide+1),NSMakeRange(j,j+blockSide+1));
Keine passende Funktion für Aufruf von object of type 'cv::Mat'cvImage.convertTo(cvImage,CV_8UC3,1.0/255.0);
Irgendwelche anderen Vorschläge?C++
? 🙂JAVA-CODE: EINE lange Zeit ist vergangen, seit diese Frage gestellt wurde, aber ich umgeschrieben habe diesen code von C++ nach Java, falls jemand es brauchen (ich brauchte, um es für die Entwicklung einer app auf android-studio).
Als das Licht ist fast in uniform, und der Vordergrund ist leicht zu unterscheiden mit dem hintergrund. So denke ich, nur direkt threshold (mit OTSU) ist ok für OCR. (Fast das gleiche mit @Andrej die Antwort im text-Regionen).
OpenCV-3-Code in Python: