The raspberry pi v2 camera (i.e., the Sony image sensor) is great since it has small unit size for the imaging pixels. Getting the raw information from the sensor is straightforward, but speed is important for getting the training done on this setup.
First thing - let's not burn the sd card! So, if you are taking lots of images, create a ramdisk to place those images!
First, make the directory:
sudo mkdir /mnt/ramdisk
Edit the rc.local file
sudo nano /etc/rc.local
Add the lines above exit 0
mount -o size=30M -t tmpfs none /mnt/ramdisk
/bin/chown pi:root /mnt/ramdisk
/bin/chmod 777 /mnt/ramdisk
Reboot, then check the file with
df -h
Now, start raspistill. In this case, we will leave it running. This way, you can take time lapse photos very quickly. Here is the command (using MATLAB syntax, but you could start it with anything that can ssh into the pi):
['nohup raspistill -n -t 0 -drc off -ss ' num2str(shutter_time) ' -ex off -awb off -ag ' num2str(analog_gain) ' -dg ' num2str(digital_gain) ' -r -s -o /mnt/ramdisk/' f_name_img ' > /dev/null 2>&1 &']
Next, get the process id from:
pgrep raspistill
And then to take a picture, you use a modified version of the kill command (strange, but it works):
['kill -USR1 ' num2str(raspistill_pid)]
Next - as you might have noticed, I don't need the whole raw image. I just need a part of it. You can write a small python script that resides on the pi that can slice the raw image. Once the .jpg file has been created, you run the python script to slice out what you need to produce a .bin file.
['python test.py -i /mnt/ramdisk/' f_name_img ' -o /mnt/ramdisk/' f_name_bin ' -s ' num2str(slice_row) ' -f ' num2str(N_slice)];
Here is the listing of test.py - pardon the indenting - you'll have to double check it if you use this script...
#!/usr/bin/python
# imports
import sys, getopt, io, os
# main, usage from the pi@raspberrypi command line:
# python test.py -i /mnt/ramdisk/image_1.jpg -o /mnt/ramdisk/hi.bin
def main(argv):
inputfile = ''
outputfile = ''
startrow = 0
stoprow = 0
# Get the inputfile and outputfile, and the start and stop row from the input arguments
try:
opts, args = getopt.getopt(argv,"hi:o:s:f:",["ifile=","ofile=","snum=","fnum="])
except getopt.GetoptError:
print 'test.py -i <inputfile> -o <outputfile> -s <startrow> -f <stoprow>'
sys.exit(2)
for opt, arg in opts:
print arg
if opt == '-h':
print 'test.py -i <inputfile> -o <outputfile> -s <startrow> -f <stoprow>'
sys.exit()
elif opt in ("-i", "--ifile"):
inputfile = arg
elif opt in ("-o", "--ofile"):
outputfile = arg
elif opt in ("-s", "--snum"):
startrow = int(arg)
elif opt in ("-f", "--fnum"):
stoprow = int(arg)
# echo the input and output file names
print 'Input file is ', inputfile
print 'Output file is ', outputfile
print 'Starting row ', startrow
print 'Stop row ', stoprow
isfile = False
# Better be a filename...
if isinstance(inputfile, str) and os.path.exists(inputfile):
isfile = True
else:
raise ValueError
if isfile:
# open the file and read the data, in bytes
file = open(inputfile, 'rb')
img = io.BytesIO(file.read())
else:
raise ValueError
# from the back of the file, the raw is the "offset"
offset = 10270208
data = img.getvalue()[-offset:]
# make sure the first bytes of the raw part at BRCM
assert data[:4] == 'BRCM'.encode("ascii")
# Check the start and stop row inputs
assert startrow >= 0
assert stoprow >= 1
assert (startrow + stoprow) <= 2479
# Slice out the rows
data_slice = data[(32768 + startrow * 4128) : (32768 + (startrow + stoprow - 1) * 4128 + 4128)]
# save the binary to the output file
f = open(outputfile, 'wb')
f.write(data_slice)
f.close()
if __name__ == "__main__":
main(sys.argv[1:])
#### Done script
So, now you can load the .bin file which just has the rows of the image that you need! Here is the MATLAB code that reads the binary raw file.
function [ret] = load_bin_raw_v2(f_name)
%% Load the binary values
% Open the jpg file
f = fopen(f_name, 'r');
% Read the file, assuming 8 bit values
bin = fread(f, '*uint8');
% Close the file
fclose(f);
%% Get the raw data and convert
% Reshape
raw_data_reshape = reshape(bin, 4128, []);
% Crop
raw_data_crop = uint16(raw_data_reshape(1 : 4100, :));
% Index for the MSBs and LSBs
temp_ind = 1 : 4100;
temp_ind = reshape(temp_ind, 5, []);
% MSBs
temp_ind_msb = temp_ind(1 : 4, :);
temp_ind_msb = reshape(temp_ind_msb, [], 1);
% LSBs
temp_ind_lsb = reshape(temp_ind(5, :), [], 1);
% The output
output = bitshift(raw_data_crop(temp_ind_msb, :), 2);
output(1 : 4 : end, :) = output(1 : 4 : end, :) + bitand(bitshift(raw_data_crop(temp_ind_lsb, :), -6), 3);
output(2 : 4 : end, :) = output(2 : 4 : end, :) + bitand(bitshift(raw_data_crop(temp_ind_lsb, :), -4), 3);
output(3 : 4 : end, :) = output(3 : 4 : end, :) + bitand(bitshift(raw_data_crop(temp_ind_lsb, :), -2), 3);
output(4 : 4 : end, :) = output(4 : 4 : end, :) + bitand(bitshift(raw_data_crop(temp_ind_lsb, :), -0), 3);
ret = output';
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.