Skip to content

Commit a813c7b

Browse files
update image capture et api pour simplifier
1 parent 9f9d39f commit a813c7b

2 files changed

Lines changed: 132 additions & 89 deletions

File tree

api.py

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@
1010
import os
1111

1212

13-
fd = None
1413
ctrl_list=dict()
1514

16-
def initialize(sensor_mode=2,v4l2_flux='/dev/video0'): # start the driver with a configurable sensor mode. (Initialization is necessary before using any other function)
17-
global fd
18-
fd = open(v4l2_flux, 'rb+', buffering=0) #open the device
15+
def initialize(fd,sensor_mode=2): # start the driver with a configurable sensor mode. (Initialization is necessary before using any other function)
1916

2017
if(fd.closed): #check if it opened well
2118
print("error : can't open ",v4l2_flux)
@@ -52,48 +49,45 @@ def initialize(sensor_mode=2,v4l2_flux='/dev/video0'): # start the driver with a
5249
line=ctrls.readline()
5350

5451
fmt = v4l2.v4l2_format()
55-
fmt.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE;
56-
fmt.fmt.pix.field = v4l2.V4L2_FIELD_NONE;
52+
fmt.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
53+
fmt.fmt.pix.field = v4l2.V4L2_FIELD_NONE
5754
if(sensor_mode==2):
5855
fmt.fmt.pix.width = 1920
5956
fmt.fmt.pix.height = 1080
60-
fmt.fmt.pix.pixelformat = v4l2.V4L2_PIX_FMT_GREY;
61-
set_control_value("sensor_mode",2)
57+
fmt.fmt.pix.pixelformat = v4l2.V4L2_PIX_FMT_GREY
58+
set_control_value(fd,"sensor_mode",2)
6259
elif(sensor_mode==0):
6360
fmt.fmt.pix.width = 1920
6461
fmt.fmt.pix.height = 1080
65-
fmt.fmt.pix.pixelformat = v4l2.V4L2_PIX_FMT_Y10;
66-
set_control_value("sensor_mode",0)
62+
fmt.fmt.pix.pixelformat = v4l2.V4L2_PIX_FMT_Y10
63+
set_control_value(fd,"sensor_mode",0)
6764
elif(sensor_mode==1):
6865
fmt.fmt.pix.width = 1920
6966
fmt.fmt.pix.height = 800
70-
fmt.fmt.pix.pixelformat = v4l2.V4L2_PIX_FMT_Y10;
71-
set_control_value("sensor_mode",1)
67+
fmt.fmt.pix.pixelformat = v4l2.V4L2_PIX_FMT_Y10
68+
set_control_value(fd,"sensor_mode",1)
7269
elif(sensor_mode==3):
73-
fmt.fmt.pix.width = 1920;
70+
fmt.fmt.pix.width = 1920
7471
fmt.fmt.pix.height = 80
75-
fmt.fmt.pix.pixelformat = v4l2.V4L2_PIX_FMT_GREY;
76-
set_control_value("sensor_mode",3)
77-
fcntl.ioctl(fd, v4l2.VIDIOC_S_FMT, fmt);
72+
fmt.fmt.pix.pixelformat = v4l2.V4L2_PIX_FMT_GREY
73+
set_control_value(fd,"sensor_mode",3)
74+
fcntl.ioctl(fd, v4l2.VIDIOC_S_FMT, fmt)
7875

79-
def close(v4l2_flux='/dev/video0'): # closes the access to the driver, must be used last, no other function must be called after this one (except if you want to do an initialization again)
76+
def close(fd): # closes the access to the driver, must be used last, no other function must be called after this one (except if you want to do an initialization again)
8077
if(fd == None):
8178
print("error : flux closed")
8279
exit(0)
8380
fd.close()
8481

8582

86-
def get_device(): # return the device
87-
return fd
88-
89-
def get_device_controls(): # return all names of controls in an array
83+
def get_device_controls(fd): # return all names of controls in an array
9084
return ctrl_list.keys()
9185

92-
def get_control_info(control_name): # return all information about control example (min, max, default value ...) in a dict.
86+
def get_control_info(fd,control_name): # return all information about control example (min, max, default value ...) in a dict.
9387
return ctrl_list[control_name]
9488

9589

96-
def set_controls(controls_dict): # use a dictionary to set controls to value
90+
def set_controls(fd,controls_dict): # use a dictionary to set controls to value
9791

9892
if(fd ==None or fd.closed): #check if file opened
9993
print("error : initialize the connection with the function initialize()")
@@ -125,10 +119,10 @@ def set_controls(controls_dict): # use a dictionary to set controls to value
125119

126120

127121

128-
def get_controls_info(): # return the dictionary with all controls informations
122+
def get_controls_info(fd): # return the dictionary with all controls informations
129123
return ctrl_list
130124

131-
def set_control_value(control_name,value): # Allows to retrieve the whole value of a control from its name.
125+
def set_control_value(fd,control_name,value): # Allows to retrieve the whole value of a control from its name.
132126
if(fd ==None or fd.closed): #check if file opened
133127
print("error : initialize the connection with the function initialize()")
134128
exit(0)
@@ -155,7 +149,7 @@ def set_control_value(control_name,value): # Allows to retrieve the whole value
155149
ecs.controls = ec # set control list into the structure
156150
fcntl.ioctl(fd, v4l2.VIDIOC_S_EXT_CTRLS, ecs) #set the control using v4l2 drivers
157151

158-
def get_control_value(control_name): # Allows to assign a value to a control from its name.
152+
def get_control_value(fd,control_name): # Allows to assign a value to a control from its name.
159153
if(fd == None or fd.closed):
160154
print("error : initialize the connection with the function initialize()")
161155
exit(0)

image_capture_example.py

Lines changed: 112 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -10,77 +10,126 @@
1010
import mmap
1111
import time
1212
import api
13-
api.initialize(sensor_mode=1)
14-
fd = api.get_device()
15-
print(">> get device capabilities")
16-
cp = v4l2.v4l2_capability()
17-
fcntl.ioctl(fd, v4l2.VIDIOC_QUERYCAP, cp)
18-
19-
20-
print(">> device setup")
21-
22-
print(">> init mmap capture")
23-
req = v4l2.v4l2_requestbuffers()
24-
req.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
25-
req.memory = v4l2.V4L2_MEMORY_MMAP
26-
req.count = 1 # nr of buffer frames
27-
fcntl.ioctl(fd, v4l2.VIDIOC_REQBUFS, req) # tell the driver that we want some buffers
28-
print("req.count", req.count)
29-
buffers = []
30-
31-
32-
print(">>> VIDIOC_QUERYBUF, mmap, VIDIOC_QBUF")
33-
for ind in range(req.count):
34-
# setup a buffer
35-
buf = v4l2.v4l2_buffer()
36-
buf.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
37-
buf.memory = v4l2.V4L2_MEMORY_MMAP
38-
buf.index = ind
39-
fcntl.ioctl(fd, v4l2.VIDIOC_QUERYBUF, buf)
40-
mm = mmap.mmap(fd.fileno(), buf.length, mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE, offset=buf.m.offset)
41-
buffers.append(mm)
42-
# queue the buffer for capture
43-
fcntl.ioctl(fd, v4l2.VIDIOC_QBUF, buf)
44-
45-
print(">> Start streaming")
46-
buf_type = v4l2.v4l2_buf_type(v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE)
47-
fcntl.ioctl(fd, v4l2.VIDIOC_STREAMON, buf_type)
48-
49-
def take_image(image_name):
50-
# IMPORTANT : Just bellow you can uncomment to clean the insternal queue of the driver
51-
# for i in range(3):
52-
# buf = v4l2.v4l2_buffer()
53-
# buf.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
54-
# buf.memory = v4l2.V4L2_MEMORY_MMAP
55-
# fcntl.ioctl(fd, v4l2.VIDIOC_DQBUF, buf) # get image from the driver queue
56-
# mm = buffers[buf.index]
57-
# mm.read(len(mm))
58-
# mm.seek(0)
59-
# fcntl.ioctl(fd, v4l2.VIDIOC_QBUF, buf)
60-
# Reactivate streaming
61-
with open(image_name, "wb") as binary_file:
13+
14+
15+
def take_image(fd,buffers,image_name): # FUNCTION TO TAKE AN IMAGE
16+
17+
# This clear the buffer of the driver carefull with this code you will use only 1/4 of the images.
18+
# Cleaning the buffer is only usefull for taking image not for video streaming ...
19+
# If you want to do a more video streaming applicaton just remove the for (the next 10 lines)
20+
for i in range(3):
6221
buf = v4l2.v4l2_buffer()
6322
buf.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
6423
buf.memory = v4l2.V4L2_MEMORY_MMAP
6524
fcntl.ioctl(fd, v4l2.VIDIOC_DQBUF, buf) # get image from the driver queue
6625
mm = buffers[buf.index]
67-
binary_file.write(mm.read(len(mm)))
26+
mm.read(len(mm))
6827
mm.seek(0)
6928
fcntl.ioctl(fd, v4l2.VIDIOC_QBUF, buf)
7029

71-
api.set_control_value("test_pattern",1)
72-
time.sleep(0.2)
73-
for i in range(1,10):
74-
api.set_control_value("test_pattern",i%2+1)
30+
31+
32+
with open(image_name, "wb") as binary_file: # Save the new image
33+
buf = v4l2.v4l2_buffer()
34+
buf.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
35+
buf.memory = v4l2.V4L2_MEMORY_MMAP
36+
fcntl.ioctl(fd, v4l2.VIDIOC_DQBUF, buf) # get image from the driver queue
37+
mm = buffers[buf.index]
38+
39+
image = mm.read(len(mm))
40+
41+
# Here you can add process to the image if you want
42+
43+
binary_file.write(image) #This is writting your image in the file
44+
mm.seek(0)
45+
fcntl.ioctl(fd, v4l2.VIDIOC_QBUF, buf)
46+
47+
48+
49+
50+
def main():
51+
52+
53+
fd = open("/dev/video0", 'rb+', buffering=0) #open the device
54+
55+
56+
# sensor mode = 0 => height=1080 width=1920 format=Y10
57+
# sensor mode = 1 => height=800 width=1920 format=Y10
58+
# sensor mode = 2 => height=1080 width=1920 format=GRAY8
59+
# sensor mode = 3 => height=800 width=1920 format=GRAY8
60+
61+
api.initialize(fd,sensor_mode=0)
62+
63+
64+
65+
66+
print(">> get device capabilities")
67+
cp = v4l2.v4l2_capability()
68+
fcntl.ioctl(fd, v4l2.VIDIOC_QUERYCAP, cp)
69+
70+
71+
print(">> device setup")
72+
73+
print(">> init mmap capture")
74+
req = v4l2.v4l2_requestbuffers()
75+
req.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
76+
req.memory = v4l2.V4L2_MEMORY_MMAP
77+
req.count = 1 # nr of buffer frames
78+
fcntl.ioctl(fd, v4l2.VIDIOC_REQBUFS, req) # tell the driver that we want some buffers
79+
print("req.count", req.count)
80+
buffers = []
81+
82+
83+
print(">>> VIDIOC_QUERYBUF, mmap, VIDIOC_QBUF")
84+
for ind in range(req.count): #create the buffers storage
85+
# setup a buffer
86+
buf = v4l2.v4l2_buffer()
87+
buf.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
88+
buf.memory = v4l2.V4L2_MEMORY_MMAP
89+
buf.index = ind
90+
fcntl.ioctl(fd, v4l2.VIDIOC_QUERYBUF, buf)
91+
mm = mmap.mmap(fd.fileno(), buf.length, mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE, offset=buf.m.offset)
92+
buffers.append(mm)
93+
# queue the buffer for capture
94+
fcntl.ioctl(fd, v4l2.VIDIOC_QBUF, buf)
95+
96+
97+
#start video streaming
98+
print(">> Start streaming")
99+
buf_type = v4l2.v4l2_buf_type(v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE)
100+
fcntl.ioctl(fd, v4l2.VIDIOC_STREAMON, buf_type)
101+
102+
103+
#all controls initialization
104+
api.set_control_value(fd,"exposure",20000)
75105
time.sleep(0.2)
76-
take_image("10bit_"+str(i)+".raw")
77-
78106

79-
print(">> Stop streaming")
80-
fcntl.ioctl(fd, v4l2.VIDIOC_STREAMOFF, buf_type)
81-
for i in buffers:
82-
i.close()
83-
api.close()
84107

85-
86-
108+
# the loop taking images
109+
110+
for i in range(0,10): #this will take 10 images
111+
112+
113+
114+
# You can add here any changes of the controls for the next image
115+
# example :
116+
#
117+
# api.set_control_value(fd,"test_pattern",i%2+1)
118+
#
119+
# this example will do an image with the first test pattern, the second image will be with
120+
# the second test pattern, the third will be with the first test pattern again ...
121+
122+
time.sleep(0.2)
123+
124+
take_image(fd,buffers,"10bit_"+str(i)+".raw") # take image changing the name to save them properly
125+
126+
127+
print(">> Stop streaming")
128+
fcntl.ioctl(fd, v4l2.VIDIOC_STREAMOFF, buf_type)
129+
for i in buffers:
130+
i.close()
131+
api.close(fd)
132+
133+
if __name__=="__main__":
134+
main()
135+

0 commit comments

Comments
 (0)