如何在opencv中通过实时相机进纸绘制透明图像

时间:2014-01-06 19:11:18

标签: opencv image-processing computer-vision

我需要在实时相机Feed上绘制透明图像。以下是要在相机Feed上显示为叠加层的png文件。

Circle image as overlay over the camera window

以下是从相机中获取帧并在屏幕上显示的代码。我还尝试将圆绘制为叠加,但圆圈不透明。我认为错误或遗漏了以下代码中的内容?

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;

int main () {

 Mat src;
 Mat overlay = imread ( "circle.png", -1 );

 VideoCapture cap ( 0 );

 while ( 1 ) {

 cap >> src;
 cvtColor( src, src, CV_BGR2BGRA );
 overlay.copyTo( src.colRange(0,400).rowRange(0,400));
 imshow ( "src",src );
 waitKey( 10 );

 }

 return 0;
 }

2 个答案:

答案 0 :(得分:2)

如果你的叠加图片有一个alpha通道(假设图片的大小相同),你可以这样做

cv::Mat display_img( src.size(), src.type() );
for (int y = 0; y < src.rows; y++)
{
    const cv::Vec3b* src_pixel = src.ptr<cv::Vec3b>(y);
    const cv::Vec4b* ovl_pixel = overlay.ptr<cv::Vec4b>(y);
    cv::Vec3b* dst_pixel = display_img.ptr<cv::Vec3b>(y);
    for (int x = 0; x < src.cols; x++, ++src_pixel, ++ovl_pixel, ++dst_pixel)
    {
        double alpha = (*ovl_pixel).val[3] / 255.0;
        for (int c = 0; c < 3; c++)
        {
            (*dst_pixel).val[c] = (uchar) ((*ovl_pixel).val[c] * alpha + (*src_pixel).val[c] * (1.0 -alpha));
        }
    }
}

答案 1 :(得分:2)

我刚刚解决了完全相同的问题,我的解决方案是找出叠加层中的哪些像素在其中有一些东西并将图像中的像素归零。现在您知道两个图像中的一个像素中的每个像素都为零,那么您可以将两个图像一起添加。

在python中:

import numpy as np
import cv2

# load the overlay file
overlay = cv2.imread('overlay.png')

# detect which pixels in the overlay have something in them
# and make a binary mask out of it
overlayMask = cv2.cvtColor( overlay, cv2.COLOR_BGR2GRAY )
res, overlayMask = cv2.threshold( overlayMask, 10, 1, cv2.THRESH_BINARY_INV)

# expand the mask from 1-channel to 3-channel
h,w = overlayMask.shape
overlayMask = np.repeat( overlayMask, 3).reshape( (h,w,3) )


# here's where the work gets done :

# mask out the pixels that you want to overlay
img *= overlayMask

# put the overlay on
img += overlay

# Show the image.
cv2.imshow(WINDOW_NAME, img)