我的目标是从扫描的名片图像中删除任何非文本区域,但我不知道使用OpenCV执行该步骤的步骤,我已按照此步骤但不知道这是正确的或不是我没有注意到图像的任何变化(非文本区域仍然存在),任何想法都会非常有用,谢谢。
1)将图像转换为灰度
2)二进制图像
3)反转颜色(cv :: bitwise_not)以获得白色像素文本
4)侵蚀图像(cv :: erode)
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);
答案 0 :(得分:6)
定义徽标的一种方法可能是徽标部分包含比文本部分更粗的线条和更大的斑点。
如果这是真的,您可以删除这样的徽标:
(我使用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中玩弄阈值,扩张内核等,看看是否可以改进。但我怀疑有一个通用的解决方案,删除所有徽标,没有文本
编辑:添加了一些图片