Ask Your Question
0

Capture one resolution from camera but display another

asked 2013-06-27 14:40:46 -0600

Nenad Bulatovic gravatar image

updated 2013-07-06 06:10:12 -0600

How can I get one resolution feed from camera in OpenCV (640x320) but cut it into half and display only one half of the frame (320x240). So not to scale down, but to actually crop. Should I use IplImage or Mat? I am quite new to OpenCV and a bit confused :)

I am using this quite standard code to get 640x480 input resolution and I made some changes to crop resolution to 320x480. Is it good or should I use Mat instead of IplImage?

// CameraFeed01.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace std;
char key;
int main()
{
    cvNamedWindow("Camera_Output", 1);    //Create window

    CvCapture* capture = cvCaptureFromCAM(1);  //Capture using camera 1 connected to system
    cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );
    cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );

    while(1){ //Create loop for live streaming

        IplImage* framein = cvQueryFrame(capture); //Create image frames from capture

        /* sets the Region of Interest  - rectangle area has to be __INSIDE__ the image */
        cvSetImageROI(framein, cvRect(0, 0, 320, 240));

        /* create destination image  - cvGetSize will return the width and the height of ROI */
        IplImage *frameout = cvCreateImage(cvGetSize(framein),  framein->depth, framein->nChannels);

        /* copy subimage */
        cvCopy(framein, frameout, NULL);

        /* always reset the Region of Interest */
        cvResetImageROI(framein);

        cvShowImage("Camera_Output", frameout);   //Show image frames on created window

        key = cvWaitKey(10);     //Capture Keyboard stroke
        if (char(key) == 27){
            break;      //ESC key loop will break.
        }
    }

    cvReleaseCapture(&capture); //Release capture.
    cvDestroyWindow("Camera_Output"); //Destroy Window
    return 0;
}
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
4

answered 2013-07-03 06:36:30 -0600

updated 2013-07-06 07:13:44 -0600

Actually what I would suggest is moving past the old C-style API and use the new C++-style API which uses the Mat element more wisely and doesn't leave you with the tricky things that IplImage pointers generate. It is actually quite simple to crop an image then and only visualizing the necessary part.

#include "stdafx.h"
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace std;
using namespace cv;

int main()
{
    //Create window
    namedWindow("Camera_Output", 1);    

    //Capture using camera 1 connected to system
    VideoCapture capture(1);  
    capture.set( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );
    capture.set( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );

    //Create loop for live streaming
    while(1){ 
        /* Create image frames from capture */
        Mat framein;
        capture >> framein; 

        /* Set the Region of Interest and apply it directly to create the output image */
        Mat frameout = framein( Rect(0, 0, 320, 240) );

        /* Show image frames on created window */
        imshow("Camera_Output", frameout);   

        /* Capture Keyboard stroke
           ESC key loop will break. */
        int key = cvWaitKey(10);     
        if (key == 27){
            break; 
        }
    }

    // Once using the C++ interface, destroying objects is done automatically by the garbage collector.
    // This is interesting because many people forget to dereference and destroy items.
    return 0;
}

It doesn't only reduce the amount of code and unnecessary calls, it also gives you the possibility to use the region of interest parameter without creating tons of new elements.

edit flag offensive delete link more

Comments

I can't compile your solution (at least not on eclipseCDT, wit hMinGW. Compiler complains about set(capture, CV_CAP_PROP_FRAME_WIDTH, 640); 'set' was not declared in this scope.

Nenad Bulatovic gravatar imageNenad Bulatovic ( 2013-07-06 05:55:38 -0600 )edit

Why I am not receiving on my email notifications that someone has replied to my question? Is there some specific setting on this forum?

Nenad Bulatovic gravatar imageNenad Bulatovic ( 2013-07-06 05:58:04 -0600 )edit

Try replacing set by VideoCapture::set and see what happens. As far as I know, you never get email notices of answers, only a red enveloppe!

StevenPuttemans gravatar imageStevenPuttemans ( 2013-07-06 06:09:26 -0600 )edit

Unfortunately VideoCapture::set won't work either. Are you using OpenCV2.4.5 as well?

Nenad Bulatovic gravatar imageNenad Bulatovic ( 2013-07-06 06:25:51 -0600 )edit

This will do the trick: capture.set(CV_CAP_PROP_FRAME_WIDTH, 640); (At least in OpenCV 2.4.5)

Nenad Bulatovic gravatar imageNenad Bulatovic ( 2013-07-06 06:29:11 -0600 )edit
1

I was simply guessing :) Don't have my workstation with me for the moment. I will adapt my code.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-07-06 07:12:25 -0600 )edit
0

answered 2013-07-06 05:56:48 -0600

Nenad Bulatovic gravatar image

My solution was a little bit different:

// CameraFeed02e.cpp : Defines the entry point for the console application.
//
#include <opencv2/opencv.hpp>
using namespace cv;

int main()
{
    // Initialize and allocate memory to load the video stream from camera
    VideoCapture camera(0);

    if (!camera.isOpened())
        return 1;

    while (true)
    {
        // Grab and retrieve each frames of the video sequentially
        Mat frame;
        camera >> frame;
        //imshow("VideoOriginal", frame); //just for debug purpose

        // Set Region of Interest to the area defined by the box
        cv::Rect roi;
        roi.x = 0;
        roi.y = 0;
        roi.width = 320;
        roi.height = 480;

        // Crop the original image to the defined ROI
        cv::Mat crop = frame(roi);
        cv::imshow("crop", crop);

        //wait for 40 milliseconds
        int c = cvWaitKey(40);

        //exit the loop if user press "Esc" key  (ASCII value of "Esc" is 27)
        if (27 == char(c))
            break;
    }

    return 0;
}
edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2013-06-27 14:40:46 -0600

Seen: 6,136 times

Last updated: Jul 06 '13