How to draw a transparent image through a live camera channel in opencv

I need to draw a transparent image on a live camera channel. Below is the png file, which will be displayed as an overlay on the camera channel.

Circle image as overlay over the camera window

Below is a snippet of code to extract frames from the camera and display it on the screen. I also tried to draw a circle as an overlay, but the circle is not transparent. I think I'm wrong or missing something in the following code snippet?

#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
source share
2 answers

If your overlay image has an alpha channel (and assuming the images are the same size), you can do something like this

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));
        }
    }
}
+2
source

​​ , , , - , . , , .

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 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)
+2

Source: https://habr.com/ru/post/1683418/


All Articles