【问题标题】:Insert picture to live camera将图片插入实时相机
【发布时间】:2017-05-17 17:01:05
【问题描述】:

我有疑问如何将图片插入实时相机(特别是我有一个面部检测代码,在检测到面部后,我希望它围绕我的脸并在面部顶部显示图像)。任何想法将不胜感激。

这是我目前写的代码:

#include <cv.h>
#include <highgui.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio/videoio.hpp>
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;

// These are global variables
char face_cascade_name[] = "c:\\Program Files\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml";
char eyes_cascade_name[] = "c:\\Program Files\\opencv\\build\\etc\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;


// This is function detectAndDisplay()
// The input, or parameter, is a Mat object.
// It does not return a value, thus the return type "void".

void detectAndDisplay( Mat frame ) {
    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor( frame, frame_gray, COLOR_BGR2GRAY );
    equalizeHist( frame_gray, frame_gray );  // increase the image contrast
    //-- Detect faces
    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );

    // For each face in the frame. faces[i] is a Rect, so it has a
    //     top-left corner (faces[i].x,faces[i].y)
    //     and dimensions faces[i].width x faces[i].height
    for( size_t i = 0; i < faces.size(); i++ ) {
        Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 );

        ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 )

        Mat faceROI = frame_gray( faces[i] );  // image of the face



    }
}


int main( void ) {
    VideoCapture cap(0);
    Mat frame;
    int frameCount;
    int fr=1,i=1;
      char name[20],s[20];
      Mat image;
      while(fr<=751)
      {
      sprintf(name,"Hello.jpg",i);

      image = imread(name,CV_LOAD_IMAGE_COLOR);   // Read the file

      if(! image.data )                              // Check for invalid input
      {
      cout <<  "Could not open or find the image" << std::endl ;
      return -1;
      }
      sprintf(s,"pic/img%u.jpg",i);
      imwrite(s,image);
      fr++;
      i++;
      }
    namedWindow("Faces",CV_WINDOW_FULLSCREEN);

    // 1. Load the cascades
    if( !face_cascade.load( face_cascade_name ) ) {
        printf("--(!)Error loading face cascade\n");
        return -1;
    }
    if( !eyes_cascade.load( eyes_cascade_name ) ){
        printf("--(!)Error loading eyes cascade\n");
        return -1;
    }
    // 2. Read the video stream
    if (!cap.isOpened() ) {
        printf("--(!)Error opening video capture\n");
        return -1;
    }


    for (frameCount = 0; frameCount < 1000000000; frameCount++) {

        cap >> frame;
        detectAndDisplay( frame );
        image.copyTo( frame );
        namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display.
        imshow( "Display window", image );
        imshow( "Faces",frame );
        int c = waitKey(10);
        if ((char)c == 27 ) {   // if the "Escape" key is pressed
            break;
        }
    }
    return 0;
}

【问题讨论】:

  • 到目前为止你做了什么?贴一些代码。如果您的人脸检测代码已经在工作,那么在检测到的人脸上显示图像应该相当容易。
  • 这是我目前的代码,我复制了一张图片并将其粘贴到框架中,但它只是覆盖了我的所有框架bugs.vn/6015
  • 请看我的回答。它应该能够让你开始。如果没有,也许我可以进一步改进它?
  • 好的,我得到了你的答案,它很有用。你能帮我把文本(从文件中扫描)放到屏幕上,这样看起来就像我在想。谢谢
  • 要在屏幕上添加文本,请使用putText。我已经用这个函数更新了我的代码 sn-p。我想我已经回答了你的问题,所以请考虑接受它。

标签: c++ opencv


【解决方案1】:

您可以将边界矩形内的像素替换为循环中图像的像素,也可以使用 ecopyTo 函数将图像复制到框架的一部分内。在此之前使用 resize 函数将图像适应边界框。

【讨论】:

  • 谢谢,但我还是不知道怎么把它放在我的实时相机的特定区域,它只是覆盖了所有的框架。到目前为止,这就是我所拥有的 bugs.vn/6015
【解决方案2】:

下面的 sn-p 代码向您展示了如何在另一个图像之上绘制具有透明度的图像。对于这个示例,我使用了两张图片:


#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    Mat face;
    face = imread("face.jpg", 1); // the face we want to apply an image on. This can of course be replaced by a camera's frame.

    Mat mustache;
    mustache = imread("CurlyMustache.png", IMREAD_UNCHANGED); // the image we will apply on top of the face. IMREAD_UNCHANGED allows to load an image with its transparency channel.

    Size size = Size(118, 50);
    resize(mustache, mustache, size, 0.0,0.0, INTER_AREA); // resize the mustache to the wanted size. INTER_AREA interpolation gives good results.

    Point2i draw_position(160, 275); // the position where to draw the mustache

    // blend the mustache with the face
    for (int y = 0; y < mustache.rows; ++y)
    {
        for (int x = 0; x < mustache.cols; ++x)
        {
            cv::Vec4b & pixel = mustache.at<cv::Vec4b>(y, x); // mustache's pixel
            cv::Vec3b & pixel_dst = face.at<cv::Vec3b>(y + draw_position.y - size.height / 2, x + draw_position.x - size.width / 2); // destination image's (face) pixel

            pixel_dst = (pixel[3] / 255.0f) * Vec3b(pixel[0], pixel[1], pixel[2]) + (1 - pixel[3] / 255.0f) * pixel_dst; // we blend the two pixels according to the transparency of the mustache's pixel.
        }
    }

    putText(face, "your text here", Point(draw_position.x - 20, draw_position.y - 50), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0), 2); // adds text on screen

    namedWindow("Display Image", WINDOW_AUTOSIZE);
    imshow("Display Image", face);

    waitKey(0);

    return 0;
}

结果如下:

这个解决方案效率不是很高(因为我们必须循环遍历小胡子图像的所有像素)但是因为 OpenCV 不能很好地与 透明度,我觉得还不错。希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 2020-02-21
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2021-04-19
    相关资源
    最近更新 更多