13

I have seen several things about capturing frames from a webcam stream using python and opencv, But how do you capture only one picture at a specified resolution with python and opencv?

a sandwhich
  • 4,352
  • 12
  • 41
  • 62
  • 1
    How is a picture different from a frame? I would guess that the camera only gives frames in its native resolution, and you have to scale them as you want them (e.g. using PIL). – Thomas K Nov 14 '10 at 21:36
  • 1
    It isn't, I should've put that differently. My cameras native resolution is 640x480, while it only displays as 320 x 240. – a sandwhich Nov 14 '10 at 22:07
  • 1
    Are you sure that 640x480 is its native resolution? I bought a webcam recently, and all the ones I looked at prominently advertised a 'software enhanced' picture resolution typically twice their real resolution in each dimension. – Thomas K Nov 14 '10 at 22:33
  • Yes I am. It is actually advertised on the box to do 720p hd. I figured out what I need to do. – a sandwhich Nov 15 '10 at 04:50

3 Answers3

11

You can capture a single frame by using the VideoCapture method of OpenCV.

import cv2

cap = cv2.VideoCapture(0) # video capture source camera (Here webcam of laptop) 
ret,frame = cap.read() # return a single frame in variable `frame`

while(True):
    cv2.imshow('img1',frame) #display the captured image
    if cv2.waitKey(1) & 0xFF == ord('y'): #save on pressing 'y' 
        cv2.imwrite('images/c1.png',frame)
        cv2.destroyAllWindows()
        break

cap.release()

Later you can modify the resolution easily using PIL.

akshaynagpal
  • 2,965
  • 30
  • 32
3

Use SetCaptureProperty :

import cv
capture = cv.CaptureFromCAM(0)
cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT, my_height)
cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH, my_width)
cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FORMAT, cv.IPL_DEPTH_32F)

img = cv.QueryFrame(capture)

Do not know how to close the camera, though.

Example of a ipython session with the above code :

In [1]: import cv

In [2]: capture = cv.CaptureFromCAM(0)

In [7]: img = cv.QueryFrame(capture)

In [8]: print img.height, img.width
480 640

In [9]: cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT, 480/2)
Out[9]: 1

In [10]: cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH, 640/2)
Out[10]: 1

In [11]: img = cv.QueryFrame(capture)

In [12]: print img.height, img.width
240 320
meduz
  • 3,903
  • 1
  • 28
  • 40
  • can you show the size of img in that case? works for me on MacOsX, opencv build using HomeBrew – meduz Apr 15 '11 at 11:46
  • According to the docs SetCaptureProperty doesn't work when using Linux with FFMPEG (don't know if that includes OSX): http://opencv.willowgarage.com/documentation/python/reading_and_writing_images_and_video.html#setcaptureproperty – AlwaysLearning Jul 31 '12 at 11:05
  • discontinued in cv2. – Krishna Mar 25 '18 at 16:25
  • discontinued? I am still using it, yet with a different syntax (in https://github.com/laurentperrinet/openRetina/blob/master/src/openRetina.py#L83 ). – meduz Mar 26 '18 at 20:18
1
import cv2
cap = cv2.VideoCapture(0)
cap.set(3,640) #width=640
cap.set(4,480) #height=480

if cap.isOpened():
    _,frame = cap.read()
    cap.release() #releasing camera immediately after capturing picture
    if _ and frame is not None:
        cv2.imwrite('img.jpg', frame)
        cv2.imwrite(name, frame)
Sreeragh A R
  • 2,871
  • 3
  • 27
  • 54
  • 4
    Just fyi to anyone stumbling across this answer that you should really never reference `_` as a variable. `_, frame = cap.read()` is fine, but `if _ :` is wholly unreadable. – JSybrandt Oct 31 '20 at 04:32