今天上午,朋友发来一张图片如下。没错,这就是原图,他希望可以通过一些简单的算法将图中这条穿过单词间的直线去掉,使得到的结果能够通过他的文字识别算法并得出正确结果——The Techniques of Machine Vision。
乍一看这似乎挺简单,(1)将图像二值化;(2)找出这条直线;(3)将直线区域填成背景色(即白色);(4)再通过膨胀、腐蚀等操作将单词缺失的部分给补全。以上4步似乎可以满足要求,但测试发现,效果不尽人意。
一、按上述方法实现过程
图1.1 对原图使用大津阈值的结果
二值化结果如图1.1所示,可以看到图像并不标准,直线粗细也不一,我们尝试用霍夫变换找一下直线,代码如下
void findLines(IplImage* raw, IplImage* dst)
{
IplImage* src = cvCloneImage(raw);
IplImage* canny = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
cvCanny(src, canny, 20, 200, 3);
CvMemStorage* stor = cvCreateMemStorage(0);
CvSeq* lines = NULL;
lines = cvHoughLines2(canny, stor, CV_HOUGH_PROBABILISTIC, 1, CV_PI / 180, 80, 200, 30);
cvZero(dst);
CvPoint maxStart, maxEnd;
int maxDistance = 0;
for (int i = 0; i < lines->total; i++)
{
CvPoint* line = (CvPoint*)cvGetSeqElem(lines, i);
if (abs(line[0].x - line[1].x) > maxDistance)
{
maxDistance = abs(line[0].x - line[1].x);
maxStart = line[0];
maxEnd = line[1];
}
}
cvLine(dst, maxStart, maxEnd, cvScalar(255), 1);
cvReleaseImage(&src);
cvReleaseMemStorage(&stor);
}
简要解释一下这段代码。函数的功能是在输入图像中找出一条直线,输入的图像是灰度图raw,返回值为dst,返回值是以图片的形式,将找到的直线画上图中。
函数