cv::detail::MultiBandBlender 照片末尾出现奇怪的白色条纹
cv::detail::MultiBandBlender strange white streaks at the end of the photo
我正在使用带有 C++11 的 OpenCV 3.4.8,我正在尝试将图像混合在一起。
在这个例子中,我有 2 个图像(下面屏幕中显示的 thiers 面具)。我有地理参考,所以我可以很容易地计算出最终图像中这些图像的角点。
masks外面的数据是黑色的。
我的代码看起来像这样:
std::vector<cv::UMat> inputImages;
std::vector<cv::UMat> masks;
std::vector<cv::Point> corners;
std::vector<cv::Size> imgSizes;
/*
here is code where I load images, create thier masks
(like in the screen above) and calculate corners.
*/
cv::Ptr<cv::detail::SeamFinder> seamFinder = new cv::detail::DpSeamFinder();
seamFinder->find(inputImages, corners, masks);
cv::Ptr<cv::detail::Blender> blender = new cv::detail:: MultiBandBlender(false);
blender->prepare(corners, imgSizes);
for(size_t i = 0; i < inputImages.size(); i++)
{
blender->feed(inputImages[i], masks[i], corners[i]);
}
cv::UMat blendedImg, outMask;
blender->blend(blendedImg, outMask);
SeamFinder 给我的结果如上图所示。找到的接缝线看起来不错,我对它们非常满意。但是另一个问题出现在下一步。当接缝线位于数据末尾时,MultiBandBlender 会产生奇怪的白色条纹。
这是一个例子:
当我不使用搅拌机,而只是使用遮罩来剪切原始图像并添加 (cv::add()
) 图像以及额外的 alpha 通道(由遮罩制成)时,我得到了非常好的结果,没有任何孔洞和奇怪的颜色,但我需要更平滑的过渡:/
谁能帮帮我?当我用更小的 num_bands 创建 MultiBand Blender 时,白色条纹更小,而 num_bands = 0 结果看起来就像只添加图像一样。
我查看了 MultiBandBlender 中的 feed()
和 blend()
方法,我认为它与高斯或拉普拉斯金字塔以及 blend()
方法中拉普拉斯金字塔的最终恢复图像有关。
编辑1:
当创建高斯和拉普拉斯金字塔 copyMakeBorder()
时,这会阻止 MultiBandBlender 在图像完全充满数据时产生这种白色条纹。所以在我的例子中,我认为我需要像 MultiBandBlender 一样创建我的搅拌机,但是 feed()
方法中的 copyMakeBorder()
方法更改为将 "extend" 我的图像在面具内的东西,就像@AlexanderKondratskiy 建议的那样。
现在我不知道如何实现类似于 BORDER_REFLECT 或 BORDER_REFLECT_101.
的正确 "extend"
我怀疑您的输入图像在这些蒙版之外包含白色像素。白色条纹出现在接缝与面罩完全一致的区域周围。例如,对于拉普拉斯算子,掩码外的像素确实会影响最终结果,因为金字塔的每一层本质上都是图像上的一些模糊核。
如果你有一些面具外的好数据,请保留它。如果你不这样做,我建议 "extending" 你的图像超出遮罩以保持平滑过渡。
编辑:
这里有两件事你可以尝试,除非有更多 OpenCV 经验的人出现。
为了 prove/disprove 我的假设,只用遮罩内的平均或中值颜色填充黑色区域。这应该使到外部区域的过渡不那么尖锐,并有望减少人工制品。如果那没有发生,我的回答是错误的。
当边缘是任意的时,就什么可能是 "BORDER_REFLECT" 的一个很好的概括而言,你可以尝试这样的事情:
- 找到遮罩多边形的质心
c
- 对于掩码外的每个像素
p
,想一想它与 c
之间的线
- 沿着这条线计算点
p'
,该点在遮罩区域内距离相同,因为 p
距遮罩边缘。 (即你沿着蒙版边缘反射)
- 从
p'
的邻居中线性插值颜色(因为它的位置可能不会恰好落在像素的中间)。那是像素的颜色 p
我正在使用带有 C++11 的 OpenCV 3.4.8,我正在尝试将图像混合在一起。 在这个例子中,我有 2 个图像(下面屏幕中显示的 thiers 面具)。我有地理参考,所以我可以很容易地计算出最终图像中这些图像的角点。 masks外面的数据是黑色的。
我的代码看起来像这样:
std::vector<cv::UMat> inputImages;
std::vector<cv::UMat> masks;
std::vector<cv::Point> corners;
std::vector<cv::Size> imgSizes;
/*
here is code where I load images, create thier masks
(like in the screen above) and calculate corners.
*/
cv::Ptr<cv::detail::SeamFinder> seamFinder = new cv::detail::DpSeamFinder();
seamFinder->find(inputImages, corners, masks);
cv::Ptr<cv::detail::Blender> blender = new cv::detail:: MultiBandBlender(false);
blender->prepare(corners, imgSizes);
for(size_t i = 0; i < inputImages.size(); i++)
{
blender->feed(inputImages[i], masks[i], corners[i]);
}
cv::UMat blendedImg, outMask;
blender->blend(blendedImg, outMask);
SeamFinder 给我的结果如上图所示。找到的接缝线看起来不错,我对它们非常满意。但是另一个问题出现在下一步。当接缝线位于数据末尾时,MultiBandBlender 会产生奇怪的白色条纹。 这是一个例子:
当我不使用搅拌机,而只是使用遮罩来剪切原始图像并添加 (cv::add()
) 图像以及额外的 alpha 通道(由遮罩制成)时,我得到了非常好的结果,没有任何孔洞和奇怪的颜色,但我需要更平滑的过渡:/
谁能帮帮我?当我用更小的 num_bands 创建 MultiBand Blender 时,白色条纹更小,而 num_bands = 0 结果看起来就像只添加图像一样。
我查看了 MultiBandBlender 中的 feed()
和 blend()
方法,我认为它与高斯或拉普拉斯金字塔以及 blend()
方法中拉普拉斯金字塔的最终恢复图像有关。
编辑1:
当创建高斯和拉普拉斯金字塔 copyMakeBorder()
时,这会阻止 MultiBandBlender 在图像完全充满数据时产生这种白色条纹。所以在我的例子中,我认为我需要像 MultiBandBlender 一样创建我的搅拌机,但是 feed()
方法中的 copyMakeBorder()
方法更改为将 "extend" 我的图像在面具内的东西,就像@AlexanderKondratskiy 建议的那样。
现在我不知道如何实现类似于 BORDER_REFLECT 或 BORDER_REFLECT_101.
我怀疑您的输入图像在这些蒙版之外包含白色像素。白色条纹出现在接缝与面罩完全一致的区域周围。例如,对于拉普拉斯算子,掩码外的像素确实会影响最终结果,因为金字塔的每一层本质上都是图像上的一些模糊核。
如果你有一些面具外的好数据,请保留它。如果你不这样做,我建议 "extending" 你的图像超出遮罩以保持平滑过渡。
编辑:
这里有两件事你可以尝试,除非有更多 OpenCV 经验的人出现。
为了 prove/disprove 我的假设,只用遮罩内的平均或中值颜色填充黑色区域。这应该使到外部区域的过渡不那么尖锐,并有望减少人工制品。如果那没有发生,我的回答是错误的。
当边缘是任意的时,就什么可能是 "BORDER_REFLECT" 的一个很好的概括而言,你可以尝试这样的事情:
- 找到遮罩多边形的质心
c
- 对于掩码外的每个像素
p
,想一想它与c
之间的线
- 沿着这条线计算点
p'
,该点在遮罩区域内距离相同,因为p
距遮罩边缘。 (即你沿着蒙版边缘反射) - 从
p'
的邻居中线性插值颜色(因为它的位置可能不会恰好落在像素的中间)。那是像素的颜色p
- 找到遮罩多边形的质心