我确实有不同的图像,这些图像都围绕着"真实的"图片。我想要实现的是找到真实的"图像(大小和位置,以像素为单位)。
对我而言,挑战在于边框并非总是黑色(可以是任何一种带有很多噪音的黑色或灰色)和“真实的”#34;图像(本例中带有鲨鱼的水)可以具有颜色,饱和度的任意组合......
现在我一般都知道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)
我已经尝试过基于例如的不同方法:
任何关于如何为(自适应)阈值和canny等算法找到适当参数(适用于所有图像)的提示以及改进处理流程的想法都将受到高度赞赏。
答案 0 :(得分:1)
您可以尝试从此图像中减去黑色图像,然后您将获得内部图像,方法是: Use image subtraction to compare images in C#,
答案 1 :(得分:1)
如果边框是均匀的,这很容易。使用cv::reduce
查找每行和每列的MIN和MAX;然后计算其中MIN和MAX与附近角落中的像素值相等(或非常接近)的顶部,左侧,底部,右侧行/列。为了理智,也许检查边框颜色是否相同。
在您的示例中,边框包含微弱的红色内容,但行/列方法可能仍然是简化问题的有用方法。也许,正如Nofar建议的那样,与你认为的背景色完全不同;将它平方,转换为灰色,然后减少为行和列的总和。您仍然需要找到边缘,但已将数据从两个维度减少到一个。
如果有大边框和大量噪音,可能会迭代:在第二遍中,从列的统计信息中排除您认为构成边框的行(反之亦然)。
编辑:以上仅适用于直立的矩形!如果它可以旋转,那么行/列投影方法将无法工作。在这种情况下,我可能会像上面那样求平方差(不要转换为灰色,因为它可能会丢弃信息),然后是模糊或某种形态,边缘检测然后某种Hough变换到找到直边。