一共这几个模块:
class videoReader 读取视频
class videoFramesExtractor(videoReader):继承了读取视频,主要是用来限制读取视频中的哪些帧,并保存。
read_excel_single(excel_path,event_instance): 处理Excel中的数组,找到事件的帧数范围:
Excel内容是这样的,需要的只是第二列的帧范围,另外第二列中的这些值还有重复的所以需要去除重复:
每一个范围,例如:23450:23461之内的帧要存放在一个文件夹里。
</pre><pre name="code" class="python"># -*- coding: cp936 -*-
import cv2.cv as cv
import os
import cv2
import numpy
import Image
import xlrd
class videoReader:
frame_count=0
def __init__(self,videoPath):
self.videoPath=videoPath
def video_init(self):
self.capture = cv.CaptureFromFile(self.videoPath)
self.win_name = "test"
cv.NamedWindow(self.win_name, cv.CV_WINDOW_AUTOSIZE)
def read(self):
self.video_init()
while 1:
self.frame_count+=1
image = cv.QueryFrame(self.capture )
cv.ShowImage(self.win_name, image)
print self.frame_count
c = cv.WaitKey(10)
if c == 27:
break
cv.DestroyWindow(self.win_name)
class videoFramesExtractor(videoReader):
save_path='d:/'
def __init__(self,videoPath,frameSpan,image_prefix):#image_prefix=event_name
videoReader.__init__(self,videoPath)
self.frameSpan=frameSpan
self.image_prefix=image_prefix
def read(self):
capture = cv2.VideoCapture(self.videoPath)
win_name = "test"
cv.NamedWindow(win_name, cv.CV_WINDOW_AUTOSIZE)
success,frame = capture.read()
init_row=0
while success:
self.frame_count+=1
success,frame = capture.read()
#cv2.imshow(win_name,frame) #显示照片浪费时间
time_duration=self.frameSpan[init_row][1]-self.frameSpan[init_row][0]+1
if self.frame_count>=self.frameSpan[init_row][0] and \
self.frame_count<=self.frameSpan[init_row][1] :
self.image_save(frame,init_row,time_duration)
if self.frame_count==self.frameSpan[init_row][1]:
init_row+=1
if init_row==len(self.frameSpan):
cv.DestroyWindow(win_name)
return 0
c = cv.WaitKey(10)
if c == 27:
break
cv.DestroyWindow(win_name)
def image_save(self,frame,init_row,time_duration):
save_path=self.make_folder(init_row,time_duration)
#frame=Image.fromarray(frame)
#frame.resize((300,300))
#frame.save('%s//%s.jpg' % (save_path,self.frame_count))
frame=cv2.resize(frame,(300,300))#
cv2.imwrite( '%s//%s.jpg' % (save_path,self.frame_count), frame)
def make_folder(self,init_row,time_duration):
temp= self.image_prefix+'_'+str(init_row)+'_'+str(time_duration)#事件名称_事件顺序_
new_path = os.path.join(self.save_path,temp)
if not os.path.isdir(new_path):
os.makedirs(new_path)
return new_path
def read_excel_single(excel_path,event_instance):
data=[]
data=xlrd.open_workbook(excel_path)
#read the first sheets
table = data.sheets()[0]
#read the num fo cols
nrows = table.nrows
rowmsg=[]#用来存储帧的范围,及事件的类别,描述。
for i in xrange(nrows):
start_frame,end_frame=table.row_values(i)[1].split(':')
rowmsg.append([int(start_frame),int(end_frame),table.row_values(i)[3]])
rowmsg.sort(lambda x,y:cmp(x[0],y[0]))#按照数字大小排序~
event_id=[]
event_id=event_instance
#print event_id
event=[]
for item in xrange(len(rowmsg)):
if rowmsg[item][2]==event_id:#
event.append(rowmsg[item])
if event==[]:
print ("there is no %s occurs" % event_instance)
return 0
#去除重复
cur_pos=1
new_rowmsg=[]
pre_s=event[0][0]
pre_e=event[0][1]
cur_s=event[cur_pos][0]
cur_e=event[cur_pos][1]
while cur_pos<len(event)-1:
while not (cur_s>pre_e):
if cur_s>pre_s:
cur_s=pre_s
if cur_e<pre_e:
cur_e=pre_e
still_pos=[cur_s,cur_e,event_id]
cur_pos+=1
if cur_pos==len(event)-1:
break
pre_s=cur_s
pre_e=cur_e
cur_s=event[cur_pos][0]
cur_e=event[cur_pos][1]
new_rowmsg.append(still_pos)
if cur_pos==len(event)-1:
break
cur_pos+=1
pre_s=cur_s
pre_e=cur_e
cur_s=event[cur_pos][0]
cur_e=event[cur_pos][1]
return new_rowmsg
excel_source='E:/08ann/dev_20071101/LGW_20071101_E1_CAM1.mpeg.xlsx'
event_instance='CellToEar'
row_msg=read_excel_single(excel_source,event_instance)
new_row=[ item[0:2] for item in row_msg ]
filename = "G:/TrecvidData/08/DEV/LGW_20071101_E1_CAM1.mpg"
videoread=videoFramesExtractor(filename,new_row,'CellToEar')
videoread.read()
cv2.的函数输出的数据类型基本都是numpy,而cv.不行。所以尽量在python中使用cv2.的函数。
通过numpy转换后的图片会在颜色上有些失真,不过影响不大,如果是灰度图的话则完全没有影响。