gpt4 book ai didi

c++ - 在 OpenCV c++ 中为相机创建透明覆盖

转载 作者:太空宇宙 更新时间:2023-11-03 22:25:51 25 4
gpt4 key购买 nike

我正在尝试为相机源创建一个叠加层,我希望该叠加层是模糊的,并且透明度大约为 50%。解决这个问题的一种方法是从相机复制每一帧,在上面绘制,然后使用 addWeighted 将它们合并在一起。这对我不起作用,因为模糊效果占用了太多资源,输出 fps 下降到 10。

我想到的另一个解决方案是创建一次叠加层(毕竟它是静态的,为什么每帧都重新创建它?)并将其与相机源合并。然而,这样做时生成的视频明显变暗,似乎是因为覆盖垫拒绝透明。

(*cap) >> frameOriginal;

orientationBackground = cv::Mat(frameOriginal.rows, frameOriginal.cols,
frameOriginal.type(), cv::Scalar(0,0,0,0));
cv::Mat headingBackground;
orientationBackground.copyTo(headingBackground);

cv::Point layerpt1(1800, 675);
cv::Point layerpt2(1850, 395);
cv::rectangle(orientationBackground, layerpt1, layerpt2,
cv::Scalar(255,80,80), CV_FILLED, CV_AA);

cv::blur(orientationBackground, orientationBackground, cv::Size(7,30));

double alpha = 0.5;
addWeighted(orientationBackground, alpha, frameOriginal, 1-alpha, 0, frameOriginal);

添加叠加层之前(左)和之后(右):overlay problem

顺便说一句,我在 Windows x64 上使用 OpenCV 3.10

最佳答案

试试这个:

    cv::Mat input = cv::imread("C:/StackOverflow/Input/Lenna.png");

// define your overlay position
cv::Rect overlay = cv::Rect(400, 100, 50, 300);

float maxFadeRange = 20;

// precompute fading mask:
cv::Size size = input.size();
cv::Mat maskTmp = cv::Mat(size, CV_8UC1, cv::Scalar(255));

// draw black area where overlay is placed, because distance transform will assume 0 = distance 0
cv::rectangle(maskTmp, overlay, 0, -1);

cv::Mat distances;
cv::distanceTransform(maskTmp, distances, CV_DIST_L1, CV_DIST_MASK_PRECISE);

cv::Mat blendingMask = cv::Mat(size, CV_8UC1);

// create blending mask from
for (int j = 0; j < blendingMask.rows; ++j)
for (int i = 0; i < blendingMask.cols; ++i)
{
float dist = distances.at<float>(j, i);

float maskVal = (maxFadeRange - dist)/maxFadeRange * 255; // this will scale from 0 (maxFadeRange distance) to 255 (0 distance)
if (maskVal < 0) maskVal = 0;

blendingMask.at<unsigned char>(j, i) = maskVal;
}

cv::Scalar overlayColor = cv::Scalar(255, 0, 0);

// color a whole image in overlay colors so that rect and blurred area are coverered by that color
cv::Mat overlayImage = cv::Mat(size, CV_8UC3, overlayColor);

// this has created all the stuff that is expensive and can be precomputed for a fixes roi overlay


float transparency = 0.5f; // 50% transparency





// now for each image: just do this:

cv::Mat result = input.clone();


for (int j = 0; j < blendingMask.rows; ++j)
for (int i = 0; i < blendingMask.cols; ++i)
{
const unsigned char & blendingMaskVal = blendingMask.at<unsigned char>(j, i);

if (blendingMaskVal) // only blend in areas where blending is necessary
{
float alpha = transparency * blendingMaskVal / 255.0f;

result.at<cv::Vec3b>(j, i) = (alpha)*overlayImage.at<cv::Vec3b>(j, i) + (1.0f - alpha)*result.at<cv::Vec3b>(j, i);
}

}

为该结果提供 50% 的透明度和 20 像素的淡化范围:

enter image description here

enter image description here

这是 20% 透明度(变量值 = 0.2f)和 100 像素褪色:

enter image description here

enter image description here

关于c++ - 在 OpenCV c++ 中为相机创建透明覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39413831/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com