我需要识别用软笔写的文字上的一些笔迹。使用 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;
}
Run Code Online (Sandbox Code Playgroud)
它确实改善了形象,但在我看来还不够好。令我印象深刻的是它在这种灰度背景下的表现。也许有人能发现问题?
我会写一个“答案”,因为评论太多了:
阴影去除(根据我的经验)并不容易,您可能对这篇论文感兴趣:“ Fredembach and Finlayson - Simple Shadow Removal ”
我不久前在解决类似问题时得到的另一个想法(我自己没有尝试过):
您基本上想要识别图像上的大区域(与字符相比)并以不同的方式对待它们。如果您知道阴影区域,您可以通过调亮较暗区域来使页面更加均匀。问题是如何获得这么大的区域。
您可以先将深色文字涂成与周围纸张相同的颜色。之后,您可以使用 OpenCV 的双边滤波器来获得大的均匀色块。您可以通过轮廓检测来识别边界,并且您会知道纸张颜色不同的地方(由阴影引起)。
希望这篇文章能够为您的问题提供新的思路并为您提供一些想法。
| 归档时间: |
|
| 查看次数: |
1742 次 |
| 最近记录: |