OpenCV从相机中裁剪实时信息

时间:2013-06-27 20:18:22

标签: c++ visual-studio-2010 opencv webcam crop

如何在OpenCV(640x320)中从相机获得正确一个分辨率馈送,但将其切成两半并仅显示帧的一半(320x240)。所以不要缩小规模,而是实际裁剪。我正在使用OpenCV 2.4.5,VS2010和C ++

这个非常标准的代码获得了640x480的输入分辨率,我对裁剪分辨率进行了一些更改为320x240。 我应该使用Mat而不是IplImage,如果是,那么最好的方法是什么?

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

4 个答案:

答案 0 :(得分:2)

我认为你不会检查你是否得到CvCapture。在我的系统只有一个摄像头,你的代码不起作用,因为你查询摄像头1.但第一个摄像头应为0因此更改此代码。

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

到(注意我将1更改为0):

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

除此之外,您的代码似乎对我有用。您也可以检查其他指针值是否未获得NULL。

答案 1 :(得分:1)

您可以通过调用以下功能轻松裁剪视频。

cvSetMouseCallback("image", mouseHandler, NULL);

mouseHandler功能就是这样。

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

有关详情,请访问以下链接:How to Crop Video from Webcam using OpenCV

答案 2 :(得分:0)

这在python中很容易......但关键的想法是可以引用和切片cv2数组。你所需要的只是framein的一部分。

以下代码从(0,0)到(320,240)获取切片。请注意,numpy数组使用列优先级编制索引。

# 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()

答案 3 :(得分:0)

从实时相机裁剪面部的工作示例

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