opencv videocapture

import time
import cv2
import numpy as np
from os import path
import pickle


'''
關於camera id 此處需要稍微說幾句。一般我們測試時,可能會通過USB使用多個攝影機,也可能是筆記型電腦自帶攝影機。這個時候,通過id號來讀攝影機的影像或者影片,
就要關於攝影機的id號到底對應哪個攝影機。在ubuntu下,我們知道打開筆記型電腦自帶攝影機是用茄子命令,即cheese,而查看攝影機的的id號,一般可以通過 ls /dev/video*,
這個命令是將所有攝影機設備都列印出來,比如列印出來有/dev/video0 /dev/video1,說明該電腦識別到兩個攝影機,此時假設筆記型電腦內置攝影機是video0,注意未必一定是0,需要測試,
我自己筆記型電腦上外接USB攝影機時,就會出現外接的攝影機是video0.此時如果我們想使用別的攝影機video1呢, cheese —device=/dev/video1,這樣就打開了另外一個攝影機了。
當然你也可以通過讀攝影機的屬性從而讀到是第幾個攝影機,這個網上有資料,稍微麻煩點。具體windows下,其實差不多,windows下可以通過設備查找。
對於ubuntu下,如果想查找各個相機對應的一些詳細屬性,可以通過工具v4l-utils,如果系統沒有安裝,則需要安裝一下(sudo apt install v4l-utils
),然後可以查看系統的相機列表(v4l2-ctl --list-devices),而後可以查看各個相機的參數,比如解析度等。(v4l2-ctl --device=/dev/video4 --list-formats-ext
),v4l2-ctl -d /dev/video0 --list-ctrls曝光增益等。具體可以參考官網://www.mankier.com/1/v4l2-ctl


'''
cam_idx = 0
#獲取cap
cam_cap = cv2.VideoCapture(cam_idx)#, cv2.CAP_DSHOW)  
#設置width,height。
cam_cap.set(3, 640)
cam_cap.set(4, 480)
# cam_cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
# cam_cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

'''
virtual bool cv::VideoCapture::set	(	int 	propId,
double 	value 
)		
virtual
Python:
cv.VideoCapture.set(	propId, value	) ->	retval
set函數的使用,其中propId是VideoCaptureProperties,詳細很多,可以看一下官方介紹。常用的有如下幾個。
CAP_PROP_POS_MSEC 
Python: cv2.CAP_PROP_POS_MSEC     Current position of the video file in milliseconds. 

CAP_PROP_POS_FRAMES 
Python: cv2.CAP_PROP_POS_FRAMES    0-based index of the frame to be decoded/captured next. 

CAP_PROP_POS_AVI_RATIO 
Python: cv2.CAP_PROP_POS_AVI_RATIO   Relative position of the video file: 0=start of the film, 1=end of the film.

CAP_PROP_FRAME_WIDTH 
Python: cv2.CAP_PROP_FRAME_WIDTH   Width of the frames in the video stream.設置video輸出的寬度,這個設置只在此程式中有效,別的程式還是默認值

CAP_PROP_FRAME_HEIGHT 
Python: cv2.CAP_PROP_FRAME_HEIGHT   Height of the frames in the video stream. 設置video輸出的高度,這個設置只在此程式中有效,別的程式還是默認值。

CAP_PROP_FPS 
Python: cv2.CAP_PROP_FPS    Frame rate.

CAP_PROP_FOURCC 
Python: cv2.CAP_PROP_FOURCC   4-character code of codec. see VideoWriter::fourcc. 影片寫入時需要設置的

CAP_PROP_FRAME_COUNT 
Python: cv2.CAP_PROP_FRAME_COUNT   Number of frames in the video file. 注意這裡是影片文件。
'''
'''
有set,就有get獲取相應的屬性。可以通過id號進行獲取,當然也可以通過屬性獲取。

cv2.VideoCapture.get(0)	CV_CAP_PROP_POS_MSEC 影片文件的當前位置(播放)以毫秒為單位
cv2.VideoCapture.get(1)	CV_CAP_PROP_POS_FRAMES 基於以0開始的被捕獲或解碼的幀索引
cv2.VideoCapture.get(2)	CV_CAP_PROP_POS_AVI_RATIO 影片文件的相對位置(播放):0=電影開始,1=影片的結尾。
cv2.VideoCapture.get(3)	CV_CAP_PROP_FRAME_WIDTH 在影片流的幀的寬度
cv2.VideoCapture.get(4)	CV_CAP_PROP_FRAME_HEIGHT 在影片流的幀的高度
cv2.VideoCapture.get(5)	CV_CAP_PROP_FPS 幀速率
cv2.VideoCapture.get(6)	CV_CAP_PROP_FOURCC 編解碼的4字-字元程式碼
cv2.VideoCapture.get(7)	CV_CAP_PROP_FRAME_COUNT 影片文件中的幀數
cv2.VideoCapture.get(8)	CV_CAP_PROP_FORMAT 返回對象的格式
cv2.VideoCapture.get(9)	CV_CAP_PROP_MODE 返回後端特定的值,該值指示當前捕獲模式
cv2.VideoCapture.get(10)	CV_CAP_PROP_BRIGHTNESS 影像的亮度(僅適用於照相機)
cv2.VideoCapture.get(11)	CV_CAP_PROP_CONTRAST 影像的對比度(僅適用於照相機)
cv2.VideoCapture.get(12)	CV_CAP_PROP_SATURATION 影像的飽和度(僅適用於照相機)
cv2.VideoCapture.get(13)	CV_CAP_PROP_HUE 色調影像(僅適用於照相機)
cv2.VideoCapture.get(14)	CV_CAP_PROP_GAIN 影像增益(僅適用於照相機)(Gain在攝影中表示白平衡提升)
cv2.VideoCapture.get(15)	CV_CAP_PROP_EXPOSURE 曝光(僅適用於照相機)
cv2.VideoCapture.get(16)	CV_CAP_PROP_CONVERT_RGB 指示是否應將影像轉換為RGB布爾標誌
cv2.VideoCapture.get(17)	CV_CAP_PROP_WHITE_BALANCE × 暫時不支援
cv2.VideoCapture.get(18)	CV_CAP_PROP_RECTIFICATION 立體攝像機的矯正標註(目前只有DC1394 v.2.x後端支援這個功能)
對應序號可以從opencv官方文件中查看得到。
enum  	cv::VideoCaptureProperties {
  cv::CAP_PROP_POS_MSEC =0,
  cv::CAP_PROP_POS_FRAMES =1,
  cv::CAP_PROP_POS_AVI_RATIO =2,
  cv::CAP_PROP_FRAME_WIDTH =3,
  cv::CAP_PROP_FRAME_HEIGHT =4,
  cv::CAP_PROP_FPS =5,
  cv::CAP_PROP_FOURCC =6,
  cv::CAP_PROP_FRAME_COUNT =7,
  cv::CAP_PROP_FORMAT =8,
  cv::CAP_PROP_MODE =9,
  cv::CAP_PROP_BRIGHTNESS =10,
  cv::CAP_PROP_CONTRAST =11,
  cv::CAP_PROP_SATURATION =12,
  cv::CAP_PROP_HUE =13,
  cv::CAP_PROP_GAIN =14,
  cv::CAP_PROP_EXPOSURE =15,
  cv::CAP_PROP_CONVERT_RGB =16,
  cv::CAP_PROP_WHITE_BALANCE_BLUE_U =17,
  cv::CAP_PROP_RECTIFICATION =18,
  cv::CAP_PROP_MONOCHROME =19,
  cv::CAP_PROP_SHARPNESS =20,
  cv::CAP_PROP_AUTO_EXPOSURE =21,
  cv::CAP_PROP_GAMMA =22,
  cv::CAP_PROP_TEMPERATURE =23,
  cv::CAP_PROP_TRIGGER =24,
  cv::CAP_PROP_TRIGGER_DELAY =25,
  cv::CAP_PROP_WHITE_BALANCE_RED_V =26,
  cv::CAP_PROP_ZOOM =27,
  cv::CAP_PROP_FOCUS =28,
  cv::CAP_PROP_GUID =29,
  cv::CAP_PROP_ISO_SPEED =30,
  cv::CAP_PROP_BACKLIGHT =32,
  cv::CAP_PROP_PAN =33,
  cv::CAP_PROP_TILT =34,
  cv::CAP_PROP_ROLL =35,
  cv::CAP_PROP_IRIS =36,
  cv::CAP_PROP_SETTINGS =37,
  cv::CAP_PROP_BUFFERSIZE =38,
  cv::CAP_PROP_AUTOFOCUS =39,
  cv::CAP_PROP_SAR_NUM =40,
  cv::CAP_PROP_SAR_DEN =41,
  cv::CAP_PROP_BACKEND =42,
  cv::CAP_PROP_CHANNEL =43,
  cv::CAP_PROP_AUTO_WB =44,
  cv::CAP_PROP_WB_TEMPERATURE =45,
  cv::CAP_PROP_CODEC_PIXEL_FORMAT =46,
  cv::CAP_PROP_BITRATE =47,
  cv::CAP_PROP_ORIENTATION_META =48,
  cv::CAP_PROP_ORIENTATION_AUTO =49,
  cv::CAP_PROP_OPEN_TIMEOUT_MSEC =53,
  cv::CAP_PROP_READ_TIMEOUT_MSEC =54
}
    '''
print (cam_cap.get(3)) # 注意返回的是浮點型數據,因此如果你要用這個返回值,注意一下數據類型。

frames = []
while (cam_cap.isOpened()):
    ret, frame = cam_cap.read()    
    if not ret:
        print ('No camera')
        break
    # import pdb 
    # pdb.set_trace()
    print (frame.shape)
    
    frame_copy = frame.copy()    
    cv2.imshow('origin', frame)
    # cv2.waitKey(0)
    if cv2.waitKey(20) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break
    
cam_cap.release()

'''
以上程式是讀影片流,直接攝影機讀入數據的,如果你要讀的是影片文件,那方式也差不多。只是更簡單。如果影片文件不存在,ret會返回False.
'''
video_file = 'SampleVideo_1280x720_1mb.mp4'
video_cap = cv2.VideoCapture(video_file)
print ('video file width',video_cap.get(3))
print ('video file height',video_cap.get(4))
print ('video file fps',video_cap.get(cv2.CAP_PROP_FPS)) # 注意這些屬性在python下使用時,沒有CV_,而C++中有的。
print ('video file totoal frames.',video_cap.get(cv2.CAP_PROP_FRAME_COUNT))
'''
video file width 1280.0
video file height 720.0
video file fps 25.0
video file totoal frames. 132.0
'''
while True:
    ret, frame = video_cap.read()
    if not ret:
        break    

    cv2.imshow('video file frame',frame)
    cv2.waitKey(25)


video_cap.release()

'''
以上都是單影片讀,如果想多個影片同時讀,可以使用多進程的方式。具體可參考另外一個程式.
'''