我的目标是从扫描的名片图像中删除任何非文本区域,但我不知道使用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);
1 回答
定义徽标的一种方法可能是徽标部分包含比文本部分更粗的线条和更大的斑点 .
如果这是真的,您可以删除这样的徽标:
(我使用imagemagick生成以下示例,你应该可以和opencv一样)
0)阈值图像(可选)
1)扩大图像直到所有字母都消失,但徽标的某些部分仍然存在 .
要么
2)使用原始图像作为掩模条件侵蚀扩张图像,直到徽标再次完成 .
这意味着您侵蚀了扩张的图像,但从未在原始源图像中将像素值设置为低于其值 . 您可以使用原始图像作为遮罩来保护图像的某些部分免受更改 .
这将恢复仍然留有一些种子部分的所有形状,因此只有徽标
要么
您现在只有徽标和没有文字的图像,使用此图像删除徽标
如你所见,它远非完美 . 也许在opencv中玩弄阈值,扩张内核等,看看是否可以改进 . 但我怀疑有一个通用的解决方案,删除所有徽标,没有任何文本
EDIT: some pictures added