OpenCV crop live feed from camera

2019-07-12 15:31发布

问题:

How can I get properly 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. I am using OpenCV 2.4.5, VS2010 and C++

This quite standard code gets 640x480 input resolution and I made some changes to crop resolution to 320x240. Should I use Mat instead of IplImage, and if so what would be the best way?

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

回答1:

I think you don't check whether you are getting a CvCapture. On my system with only one camera your code doesn't work because you query camera 1. But the first camera should be 0 Thus change this code.

CvCapture* capture = cvCaptureFromCAM(1);  //Capture using camera 1 connected to system

to (note I change 1 to 0):

CvCapture* capture = cvCaptureFromCAM(0);  //Capture using camera 1 connected to system
if (! capture ){
    /*your error handling*/
}

Further than that your code seems to be working for me. You might also check the other pointer values whether you are not getting NULL.



回答2:

You can easily crop a video by calling the following function.

cvSetMouseCallback("image", mouseHandler, NULL);

The mouseHandler function is like that.

void mouseHandler(int event, int x, int y, int flags, void* param){
    if (event == CV_EVENT_LBUTTONDOWN && !drag)
    {
        /* left button clicked. ROI selection begins */
        select_flag=0;
        point1 = Point(x, y);
        drag = 1;
    }

    if (event == CV_EVENT_MOUSEMOVE && drag)
    {
        /* mouse dragged. ROI being selected */
        Mat img1 = img.clone();
        point2 = Point(x, y);
        rectangle(img1, point1, point2, CV_RGB(255, 0, 0), 3, 8, 0);
        imshow("image", img1);
    }

    if (event == CV_EVENT_LBUTTONUP && drag)
    {
        point2 = Point(x, y);
        rect = Rect(point1.x,point1.y,x-point1.x,y-point1.y);
        drag = 0;
        roiImg = img(rect);
    }

    if (event == CV_EVENT_LBUTTONUP)
    {
       /* ROI selected */
        select_flag = 1;
        drag = 0;
    }
}

For the details you can visit the following link.:How to Crop Video from Webcam using OpenCV



回答3:

this is easy in python... but the key idea is that cv2 arrays can be referenced and sliced. all you need is a slice of framein.

the following code takes a slice from (0,0) to (320,240). note that numpy arrays are indexed with column priority.

# Required modules
import cv2

# Constants for the crop size
xMin = 0
yMin = 0
xMax = 320
yMax = 240

# Open cam, decode image, show in window
cap = cv2.VideoCapture(0) # use 1 or 2 or ... for other camera
cv2.namedWindow("Original")
cv2.namedWindow("Cropped")
key = -1
while(key < 0):
    success, img = cap.read()

    cropImg = img[yMin:yMax,xMin:xMax] # this is all there is to cropping

    cv2.imshow("Original", img)
    cv2.imshow("Cropped", cropImg)

    key = cv2.waitKey(1)
cv2.destroyAllWindows()


回答4:

Working Example of cropping Faces from live camera

    void CropFaces::DetectAndCropFaces(Mat frame, string locationToSaveFaces) {    
     std::vector<Rect> faces;
     Mat frame_gray;

     // Convert to gray scale
     cvtColor(frame, frame_gray, COLOR_BGR2GRAY);

     // Equalize histogram
     equalizeHist(frame_gray, frame_gray);

     // Detect faces
     face_cascade.detectMultiScale(frame_gray, faces, 1.1, 3,
      0 | CASCADE_SCALE_IMAGE, Size(30, 30));

     // Iterate over all of the faces
     for (size_t i = 0; i < faces.size(); i++) {

      // Find center of faces
      Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);

      Mat face = frame_gray(faces[i]);
      std::vector<Rect> eyes;

      Mat croppedRef(frame, faces[i]);

      cv::Mat cropped;
      // Copy the data into new matrix
      croppedRef.copyTo(cropped);

      string fileName = locationToSaveFaces+ "\\face_" + to_string(faces[i].x) + ".jpg";
      resize(cropped, cropped, Size(65, 65));
      imwrite(fileName, cropped);
     }
     // Display frame
     imshow("DetectAndSave", frame);
    }


    void CropFaces::PlayVideoForCropFaces(string locationToSaveFaces) {    
     VideoCapture cap(0); // Open default camera
     Mat frame;
     face_cascade.load("haarcascade_frontalface_alt.xml"); // load faces

     while (cap.read(frame)) {
      DetectAndCropFaces(frame, locationToSaveFaces); // Call function to detect faces
      if (waitKey(30) >= 0)    // pause
       break;
     }
    }