首页 文章

在图像中查找图像(对象检测)

提问于
浏览
1

我确实有不同的图像,它们都围绕着“真实”的图像有某种边界 . 我想要实现的是找到“真实”图像(像素的大小和位置) .

real image showing water with shark

对我来说,挑战是边框并不总是黑色(可以是任何一种黑色或灰色,噪音很大)和“真实”图像(本例中带有鲨鱼的水)可以有任何颜色,饱和度的组合, ...

现在一般我都知道Canny,Blob检测,hough行等算法......但我刚刚开始使用它们 . 到目前为止,我设法找到特定图像的边框,但是一旦我尝试将相同的算法和参数应用到下一个图像,它就不起作用 . 我目前的方法看起来像这样(伪代码):

  • 转换为灰色 CvInvoke.CvtColor(_processedImage, tempMat, CvEnum.ColorConversion.Rgb2Gray)
    使用 CvInvoke.PyrDown(srcImage, targetImage)CvInvoke.PyrUp(srcImage, targetImage)

  • 下采样

  • 使用 CvInvoke.GaussianBlur(_processedImage, bluredImage, New Drawing.Size(5, 5), 0) 模糊图像

  • 二进制化 CvInvoke.Threshold(_processedImage, blackWhiteImage, _parameters.BinarizeThreshold, 255, CvEnum.ThresholdType.Binary)

  • 使用 CvInvoke.Canny(_processedImage, imgEdges, 60, 100) 检测边缘

  • 使用`CvInvoke.FindContours(_processedImage,contours,Nothing,CvEnum.RetrType.External,CvEnum.ChainApproxMethod.ChainApproxSimple)查找轮廓

  • 假设最大轮廓是真实图像

我已经尝试过基于例如的不同方法:

任何关于如何为(自适应)阈值和canny等算法找到适当参数(适用于所有图像)的提示以及改进处理流水线的想法都将受到高度赞赏 .

2 回答

  • 1

    您可以尝试从此图像中减去黑色图像,然后您将获得内部图像,方法是:Use image subtraction to compare images in C#

  • 1

    如果边界是统一的,这很容易 . 使用 cv::reduce 查找每行和每列的MIN和MAX;然后计算其中MIN和MAX与附近角落中的像素值相等(或非常接近)的顶部,左侧,底部,右侧行/列 . 为了理智,也许检查边框颜色是否相同 .

    在您的示例中,边框包含微弱的红色内容,但行/列方法可能仍然是简化问题的有用方法 . 也许,正如Nofar建议的那样,与你认为的背景色完全不同;将它平方,转换为灰色,然后减少为行和列的总和 . 您仍然需要查找边缘,但已将数据从两个维度减少到一个 .

    如果存在大的边界和大量噪声,可以迭代:在第二遍中,从列的统计数据中排除您认为构成边界的行(反之亦然) .

    编辑:以上只适用于直立的矩形!如果它可以旋转,那么行/列投影方法将不起作用 . 在这种情况下,我可能会像上面那样求平方差的平方(不要开始转换为灰色,因为它可能丢弃信息),然后是模糊或一些形态,边缘检测然后某种Hough变换直接找到边缘 .

相关问题