سؤال

I am trying to draw a face outline and overlay it on top of a webcam image.

But towards the end, I think I am using addWeighted in a wrong way, because my program crashes.

Could you please help me understand what I am doing wrong with imshow and addWeighted?

int main( int argc, const char** argv )
{
  VideoCapture camera;
  camera.open(0);

  if( !camera.isOpened() )
  {
    cerr << "Could not access the camera!" << endl;
    return  1;
  }

  while( true )
  {
    Mat cameraFrame;
    camera >> cameraFrame;

    if( cameraFrame.empty() )
    {
      cerr << "Could not grab a camera frame!" << endl;
      return  1;
    }

    Mat gray;
    cvtColor( cameraFrame, gray, CV_BGR2GRAY );
    Size size = cameraFrame.size();
    Mat faceOutline = Mat::zeros( size, CV_8UC3 );      // Draw a black canvas.
    Scalar color = CV_RGB( 255, 255, 0 );               // Yellow
    int thickness = 4;
    ellipse( faceOutline, Point(320, 240), Size(320, 240), 0, 0, 360, color, thickness, CV_AA );
    addWeighted( gray, 1.0, faceOutline, 0.7, 0, gray, CV_8UC3 );
    imshow( "final image", gray );

    char keypress = waitKey(20);
    if( keypress == 27 ) break;
  }
}
هل كانت مفيدة؟

المحلول

This works fine:

int main( int argc, const char** argv )
{
    VideoCapture camera;
    camera.open(0);

    if( !camera.isOpened() )
    {
        cerr << "Could not access the camera!" << endl;
        return  1;
    }

    while( true )
    {
        Mat cameraFrame;
        camera >> cameraFrame;

        if( cameraFrame.empty() )
        {
            cerr << "Could not grab a camera frame!" << endl;
            return  1;
        }

        Mat gray;
        cvtColor( cameraFrame, gray, cv::COLOR_BGR2GRAY );
        Size size = cameraFrame.size();
        Mat faceOutline = Mat::zeros( size, CV_8UC3 );      // Draw a black canvas.
        Scalar color = Scalar( 255, 255, 0 );               // Yellow
        int thickness = 4;
        cvtColor( gray, gray, cv::COLOR_GRAY2BGR );
        ellipse( faceOutline, Point(320, 240), Size(320, 240), 0, 0, 360, color, thickness );
        addWeighted( gray, 1.0, faceOutline, 0.7, 0, gray, CV_8UC3 );
        imshow( "final image", gray );
        char keypress = waitKey(20);
        if( keypress == 27 ) break;
    }
}

نصائح أخرى

  • why not just draw the ellipse into the cameraFrame ?

    ellipse( cameraFrame , Point(320, 240), Size(320, 240), 0, 0, 360, color, thickness, CV_AA );

  • and if you want to use addWeighted,

    1. the type of both input images has to match ( you can't add a color to a grayscale image )
    2. the factors have to sum up to 1.0
    3. the last argument is depth, not type ( i.e you could convert it to float here, but not change the number of channels)

    addWeighted( cameraFrame , 0.7, faceOutline, 0.3, 0, cameraFrame );

I suppose your gray image is single-channel and your faceOutline image has 3 channels.

From the documentation:

src2 – second input array of the same size and channel number as src1.

Try mixChannels to switch a single channel of a multichannel image

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top