【发布时间】:2014-05-23 15:15:44
【问题描述】:
我需要识别用软笔书写的文字上的一些笔迹。使用 OpenCV、不同的阈值方法、双边过滤等,我从纸上提取文本得到了很好的结果。但我也从折叠中得到文物:
在处理纸张之前,我无法更改处理或拍照的方式。对同一篇论文进行阈值处理后如下所示:
我想删除这些工件。对我来说最大的麻烦是当像“T”这样的字符恰好在这条线上的情况。 “T”的水平部分可能很适合这条线。
我现在做什么:我可以检测是否有独立线路。如果某个东西高几个像素而且很宽,我会删除它。
我一直在阅读很多关于消除阴影的信息(因为我认为问题是阴影)。但他们都希望在其他环境中工作 - 监控视频源或具有彩色背景的图像。
有什么想法吗?
更新:
正在研究基于类似作品的想法:http://ivrgwww.epfl.ch/alumni/fredemba/papers/FFICPR06.pdf
测试输入
测试代码的输出:
源代码:
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int filt1_trackbar=13;
int filt2_trackbar=49;
int filt3_trackbar=6;
int main( int argc, char** argv ) {
Mat src, shadow;
src = imread( argv[1], 1 );
if( !src.data ) {
return -1;
}
Mat histImage1( src.rows, src.cols, CV_8UC3, Scalar(127,127,127) );
Mat histImage2( src.rows, src.cols, CV_8UC3, Scalar(127,127,127) );
int cn = src.channels();
uint8_t* pixelPtr = (uint8_t*)src.data;
for(int i=0 ; i< src.rows;i++) {
for(int j=0 ; j< src.cols;j++) {
Scalar_<uint8_t> bgrPixel;
bgrPixel.val[0] = pixelPtr[i*src.cols*cn + j*cn + 0]; // B
bgrPixel.val[1] = pixelPtr[i*src.cols*cn + j*cn + 1]; // G
bgrPixel.val[2] = pixelPtr[i*src.cols*cn + j*cn + 2]; // R
if(bgrPixel.val[2] !=0 ) { // avoid division by zero
float a= 100.0*(((float)bgrPixel.val[0] / (float)bgrPixel.val[2])); // B/R
float b= 100.0*(((float)bgrPixel.val[1] / (float)bgrPixel.val[2])); // G/R
if(!isinf(a) && !isinf(b)) {
histImage1.at<Vec3b>(i,j)=Vec3b(a,a,a);
histImage2.at<Vec3b>(i,j)=Vec3b(b,b,b);
}
}
}
}
addWeighted(histImage1, 2.0, histImage2, -1.0, 0, shadow);
Mat hsv1,hsv2;
cvtColor(shadow, hsv1, CV_BGR2HSV);
cvtColor(src, hsv2, CV_BGR2HSV);
vector<Mat> channels1;
vector<Mat> channels2;
split(hsv1, channels1);
split(hsv2, channels2);
addWeighted(channels1[2], 0.5, channels2[2], 0.5, 0, channels1[2]);
insertChannel(channels1[2],hsv2,2);
Mat unshadow;
cvtColor(hsv2,unshadow, CV_HSV2BGR);
namedWindow( "src", WINDOW_NORMAL);
namedWindow( "shadow", WINDOW_NORMAL);
namedWindow( "unshadow", WINDOW_NORMAL);
imshow("src", src);
imshow("shadow", shadow);
imshow("unshadow", unshadow);
imwrite("shadow.png", shadow);
imwrite("unshadow.png", unshadow);
waitKey(0);
return 0;
}
它确实改善了形象,但在我看来还不够好。我印象深刻的是它在这样的灰度背景下完全有效。也许有人能发现不对劲?
【问题讨论】:
-
看看他们如何找到数独的水平和垂直线:stackoverflow.com/questions/10196198/…你的问题应该是相似的
-
谢谢。看过这个线程,发现它对于学习 OpenCV 和计算机视觉非常有用。但我在纸上也有其他线条,我不想删除。我可以检测线条并删除。但后来我也松开了在线写的文字。至少我是这么认为的。印刷线质量相当高。折叠文物可能有未知的形状和宽度:(
标签: opencv