2017-05-12 19 views
-2

ライブカメラに画像を挿入する方法について質問があります(特に、顔を検出した後、顔検出コードを持っています。顔を丸くして、画像を上に表示したい面)。任意のアイデアをいただければ幸いです。ここでライブカメラに画像を挿入する

私がこれまでに書いたコードです:

#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; 
} 
+0

あなたはこれまで何をしていますか?いくつかのコードを投稿してください。すでに顔検出コードが機能している場合は、検出された顔の上に画像を表示するのは簡単です。 –

+0

これはこれまでの私のコードですが、イメージをコピーしてフレームに貼り付けていますが、それはすべてのフレームをカバーしています。https://bugs.vn/6015 –

+0

私の答えをご覧ください。それはあなたを始めることができるはずです。もしそうでなければ、私はそれをさらに改善することができますか? –

答えて

0

をあなたは、ループ内のあなたのイメージのピクセルと矩形の境界内のピクセルを置き換えることができるか、あなたの一部の内側にあなたのイメージをコピーするecopyTo機能を使用することができますフレーム。その前に、イメージをバウンディングボックスに合わせるためのサイズ変更機能を使用します。

+0

ありがとうございます。しかし、私はライブカメラの特定の地域にどのように置いているのかまだ分かりません。すべてのフレームをカバーしています。これまでのところ、これは私がhttps://bugs.vn/6015を持っているものです –

0

次のスニペットコードは、透過度でイメージを別のイメージの上に描画する方法を示しています。このサンプルのために、私は2枚の画像を使用する:


#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; 
} 

結果は次のとおりです。

man's face with a mustache

このソリューションは非常に効率的な(私たちは口ひげの画像の全画素をループに持っているように)が、としてOpenCVの透明とあまりにもよく混同していないではないですが、私は考えますそれはまともなものです。それが役に立てば幸い!