0
我处理canny边缘检测后,我得到了边缘图像。 但我只是想保持短边(边缘来自人物)。 还有一些长边(这里我定义长度超过图片高度的一半)。示例图片看起来像: 如何去除Canny边缘图像中的长边?
那么如何删除跨过图片高度的一半以上的边缘?
相关问题: remove horizontal/vertical long edges
我处理canny边缘检测后,我得到了边缘图像。 但我只是想保持短边(边缘来自人物)。 还有一些长边(这里我定义长度超过图片高度的一半)。示例图片看起来像: 如何去除Canny边缘图像中的长边?
那么如何删除跨过图片高度的一半以上的边缘?
相关问题: remove horizontal/vertical long edges
您可以应用在包含边缘minAreaRect
一些约束。 您可以找到一个示例here,但由于您的边缘触摸边框,因此需要额外的技巧才能使findContours
正常工作,因此在改进的代码下面。
随着纵横比简单的约束,您可以:
,你删除红色边缘:
您可以添加额外的contraint,例如在height
,以适应您的具体目的。
下面的代码:
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
// Load image
Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
// Remove JPG artifacts
img = img > 200;
Mat1b result = img.clone();
// Create output image
Mat3b out;
cvtColor(img, out, COLOR_GRAY2BGR);
// Find contours
Mat1b padded;
copyMakeBorder(img, padded, 1, 1, 1, 1, BORDER_CONSTANT, Scalar(0));
vector<vector<Point>> contours;
findContours(padded, contours, RETR_LIST, CHAIN_APPROX_NONE, Point(-1, -1));
for (const auto& contour : contours)
{
// Find minimum area rectangle
RotatedRect rr = minAreaRect(contour);
// Compute aspect ratio
float aspect_ratio = min(rr.size.width, rr.size.height)/max(rr.size.width, rr.size.height);
// Define a threshold on the aspect ratio in [0, 1]
float thresh_ar = 0.05f;
// Define other constraints
bool remove = false;
if (aspect_ratio < thresh_ar) {
remove = true;
}
// if(some_other_constraint) { remove = true; }
Vec3b color;
if (remove) {
// Almost straight line
color = Vec3b(0, 0, 255); // RED
// Delete edge
for (const auto& pt : contour) {
result(pt) = uchar(0);
}
}
else {
// Curved line
color = Vec3b(0, 255, 0); // GREEN
}
// Color output image
for (const auto& pt : contour) {
out(pt) = color;
}
}
imshow("Out", out);
imshow("Result", result);
waitKey();
return 0;
}
太好了!感谢您的解决方案。你能给我一些关于如何去除我不需要的其他边缘的建议吗(比如右边的边缘,但它们不够长)? – Zieng
稍微增加'thresh_ar',例如到0.075或0.1。对信件的最大高度进行一些限制......类似这样的内容......它对你的上下文非常具体。有了边缘,只有你可以去掉一些噪音,但是你需要更强大的东西去除你所有的字母 – Miki
非常感谢。我会试一下! – Zieng