我觉得自己有点像OpenCV技能的工作-并且学到了很多-很酷的问题!
我生成了一个包含alpha值的单通道图像-浮动以减少舍入错误,并生成单个通道以节省一些内存.这表示您的圆圈在背景中可见多少.
该圆具有一个外部半径(在该点处它完全透明)和一个内部半径(该点停止处完全不透明).这两个之间的半径将消失.因此,将IRADIUS设置为非常接近ORADIUS,以实现陡峭,快速的衰减,并且将其设置在较远的位置,以使逐渐变细.
我使用ROI将圆圈定位在背景上,并通过仅在背景的必要矩形上进行迭代来加快处理速度.
唯一棘手的部分是Alpha混合或合成.您只需要知道输出图像中每个像素的公式为:
out = (alpha * foreground) + (1-alpha) * background
这是代码.我在OpenCV上并不是世界上最好的,所以可能有些零件可以优化!
// main.cpp
// Mark Setchell
#include
#include
#include
using namespace std;
using namespace cv;
#define ORADIUS 100 // Outer radius
#define IRADIUS 80 // Inner radius
int main()
{
// Create a blue background image
Mat3b background(400,600,Vec3b(255,0,0));
// Create alpha layer for our circle normalised to 1=>solid, 0=>transparent
Mat alpha(2*ORADIUS,2*ORADIUS,CV_32FC1);
// Now draw a circle in the alpha channel
for(auto r=0;r(r,c);
if(radius>ORADIUS){ pixel=0.0; continue;} // transparent
if(radius(j);
thisFgRow = circle.ptr(j);
thisAlphaRow = alpha.ptr(j);
for(int i=0;i((thisFgRow[i][c]*thisAlphaRow[i]) + ((1.0-thisAlphaRow[i])*thisBgRow[i][c]));
}
}
}
imwrite("result.png",background);
return 0;
}
这是与IRADIUS = 80:
这是与IRADIUS = 30:
感谢并感谢@Micka共享他的代码来迭代ROI here.
糟糕,我刚刚意识到您正在寻找Python解决方案.希望我的代码能为您提供一些生成软圆形蒙版的想法,并且我找到了一篇文章here,向您展示了一些Python样式的实现方式,您可以将它们与我的代码混在一起.