我需要识别用软笔写的文字上的一些笔迹.使用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;
}
它确实改善了图像,但在我看来还不够好.我对这种灰度背景下的工作印象深刻.也许有人可以发现错误?
最佳答案 我会写一个“答案”因为评论太多了:
阴影去除(根据我的经验)并不容易,您可能对本文感兴趣:“Fredembach and Finlayson – Simple Shadow Removal”
我在处理类似问题时得到了一段时间的另一个想法(我自己没有尝试过):
您基本上想要识别图像上的大区域(与字符相比)并以不同方式对待它们.如果你知道阴影区域,你可以通过增亮较暗的区域使页面更均匀.问题是如何获得这个大区域.
您可以先将黑色书写与周围纸张相同的颜色进行着色.之后,您可以使用OpenCV的双边滤镜来获得大的均匀色块.您可以通过轮廓检测识别边框,并且您可以知道纸张颜色的不同(由阴影引起).
希望这篇文章能够为你的问题带来新的亮点,并为你提供一些想法.