我的目标是从扫描的名片图像去除任何非文本区域,但我不知道要执行使用OpenCV的,我按照这个步骤的步骤,但不知道这是正确的还是不还我不不会注意到图像的任何变化(非文本区域依然是)任何想法会有很大的帮助,谢谢。
1)将图像转换为灰度
2)二进制文件图像
3)为了有一个白色像素文本反转的颜色(CV :: bitwise_not)
4)侵蚀图像(CV ::侵蚀)
5)检测用Canny边缘
6)使用hough变换(尚未检测文本行)
码:
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);
定义标识的一种方式可能是标志部分包含除文本部分胖的线条和较大的斑点。
如果成立,你可以删除这样的标志:
(我用的ImageMagick生成以下样品,你应该能够与OpenCV的相同)
0)的阈值的图像(可选)
imagemagick: convert 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
要么
imagemagick: convert 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
要么
imagemagick: convert dilated.png -morphology erode:20 diamond -clip-mask monochrome.png eroded.png
你现在有一个图像时,仅标识和没有文本,使用此图片删除标志
imagemagick: convert eroded.png -negate img0052ir.jpg -compose plus -composite test.png
正如你所看到的,这是远远不够完善。 或许玩具与周围的阈值,扩张内核等,在OpenCV中,看看是否能得到改善。 但我怀疑有一个通用的解决方案的文本,消除所有的标志和无
编辑:一些图片添加