我想知道如何在OpenCV中实现类似发光球或发光线的效果。您有什么建议,我可以从哪里开始或使用什么工具来创建输出中的简单动画?谢谢!
mask
中的白色区域。使用GaussianBlur
模糊该蒙版,然后将结果与您的源图像img
合并。对于发光效果,您可能需要类似于Photoshop的屏幕混合模式,这将只增亮图像:
结果颜色=255-[((255-顶部颜色)*(255-底部颜色))/ 255]
"发光"效果的真正关键是将底层的像素用作屏幕层。这在OpenCV中的实现方式如下:
cv::Mat mask, img;
...
mask = mask * img; //fill the mask region with pixels from the original image
cv::GaussianBlur(mask, mask, cv::Size(0,0), 4); //blur the mask, 4 pixels radius
mask = mask * 0.50; //a 50% opacity glow
img = 255 - ((255 - mask).mul(255 - img) / 255); //mul for per-element multiply
我没有测试这段代码,所以可能有些地方有误。颜色减淡也是一种对于发光效果非常有用的混合模式。
更多信息请参考:Photoshop如何将两张图片混合在一起?
我编写了一个版本的效果,可以在CPU和HW加速设备(例如GPU)上运行。如果src是cv :: UMat并且您支持OpenCL,则它将使用OpenCL运行,否则如果src是cv :: Mat,则将运行旧的CPU代码。
template<typename Tmat>
void glow_effect(Tmat& src, int ksize = 100) {
static Tmat resize;
static Tmat blur;
static Tmat src16;
cv::bitwise_not(src, src);
//Resize for some extra performance
cv::resize(src, resize, cv::Size(), 0.5, 0.5);
//Cheap blur
cv::boxFilter(resize, resize, -1, cv::Size(ksize, ksize), cv::Point(-1, -1), true, cv::BORDER_REPLICATE);
//Back to original size
cv::resize(resize, blur, cv::Size(VIDEO_WIDTH, VIDEO_HEIGHT));
//Multiply the src image with a blurred version of itself
cv::multiply(src, blur, src16, 1, CV_16U);
//Normalize and convert back to CV_8U
cv::divide(src16, cv::Scalar::all(255.0), src, 1, CV_8U);
cv::bitwise_not(src, src);
}