如何使用OpenCV从名片中删除非文本区域?

cho*_*vil 0 c++ ocr opencv image-processing image-segmentation

我的目标是从扫描的名片图像中删除任何非文本区域,但我不知道使用OpenCV执行该操作的步骤,我已按照这些步骤但不知道这是正确的,或者我也不知道注意图像中的任何变化(非文本区域仍然存在)任何想法将非常有用,谢谢.

1)将图像转换为灰度

2)二进制图像

3)反转颜色(cv :: bitwise_not)以获得白色像素文本

4)侵蚀图像(cv :: erode)

5)使用canny检测边缘

6)使用霍夫变换检测文本行(尚未)

码:

cv::Mat greyMat = [self.imageView.image CVGrayscaleMat];
cv::Mat bwMat;
cv::threshold(greyMat, bwMat, 128, 255, CV_THRESH_BINARY);
cv::bitwise_not(bwMat, bwMat);
cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2, 1));
cv::erode(bwMat, bwMat, element);
std::vector<cv::Point>points;
cv::Mat_<uchar>::iterator it=bwMat.begin<uchar>();
cv::Mat_<uchar>::iterator end=bwMat.end<uchar>();
for (; it!=end; ++it) 
if (*it) 
points.push_back(it.pos());
cv::RotatedRect box=cv::minAreaRect(cv::Mat(points));
plImage* smothedImage=new IplImage(bwMat); 
cvSmooth(smothedImage, smothedImage);
cvCanny(smothedImage, smothedImage, 10, 100);
Run Code Online (Sandbox Code Playgroud)

Hug*_*une 6

定义徽标的一种方法可能是徽标部分包含比文本部分更粗的线条和更大的斑点.

如果这是真的,您可以删除这样的徽标:

(我使用imagemagick生成以下示例,你应该可以和opencv一样)

0)阈值图像(可选)

   imagemagick: convert img0052ir.jpg -threshold 60% monochrome.png
Run Code Online (Sandbox Code Playgroud)

输出:转换img0052ir.jpg -threshold 60%monochrome.png

1)扩大图像直到所有字母都消失,但徽标的某些部分仍然存在.

 orgImg = business card image 
 cvDilate (orgImg, curImg, null, Some_Value) // find a value that erases all letters but leaves the logo
Run Code Online (Sandbox Code Playgroud)

要么

 imagemagick:  convert monochrome.png -morphology dilate:3 diamond dilated.png
Run Code Online (Sandbox Code Playgroud)

connvert monochrome.png -morphology dilate的输出:3 diamond dilated.png

2)使用原始图像作为掩模条件侵蚀扩张图像,直到徽标再次完成.

这意味着您侵蚀了扩张的图像,但从未在原始源图像中将像素值设置为低于其值.您可以使用原始图像作为遮罩来保护图像的某些部分免受更改.

这将恢复仍然留有一些种子部分的所有形状,因此只有徽标

 // Not sure if opencv can use a mask in morphologial operations, 
 // but you can just use erode + max in a loop to achive the same effect albeit slower
 repeat
    lastImg = curImg
    cvErode (lastImg, curImg, null ,1)
    cvMax (curImg, orgImg, curImg)
 until lastImg == curImg
Run Code Online (Sandbox Code Playgroud)

要么

 imagemagick: convert dilated.png -morphology erode:20 diamond -clip-mask monochrome.png eroded.png
Run Code Online (Sandbox Code Playgroud)

convert dilated.png-morphy的输出erode:20 diamond -clip-mask monochrome.png eroded.png

您现在只有徽标和没有文字的图像,使用此图像删除徽标

 imagemagick: convert eroded.png -negate img0052ir.jpg -compose plus -composite test.png
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如你所见,它远非完美.也许在opencv中玩弄阈值,扩张内核等,看看是否可以改进.但我怀疑有一个通用的解决方案,删除所有徽标,没有任何文本

编辑:添加了一些图片