how to read serial pixel data into matrix without having to perform transpose operation

3 views (last 30 days)
I'm currently working with raw 12 bit data aquired from an Allied Vision camera. I can demosiac the data successfully, but I'm having to perform a transpose operation that I feel is uncessary if I can figure out how to read the serial pixel data into a matrix properly. I also need to scale all the 12 bit pixel intensity values to 16 bit and wonder if there is a combo operation that can perform the scale and transpose operations in a single operation.
Here's my .m file.
% width and height of raw 12 bit data
width = 5328;
height = 4608;
% open raw bayer 12 bit data
% first row: RGRGRG...
% second row: GBGBGB...
fd = fopen("~/Downloads/230221_170357_000_exp00000960_gain0013_BayerRG12.raw") % modify with your image path
% read data into 16 bit word array
%
% NOTE: raw 12 bit data has already been converted into a
% 16 bit word spacing file, but 12 bit values have not
% been scaled yet (see scaling step after reading data)
word_array_16_bit = fread(fd, width*height, 'uint16=>uint16');
% scale 12 bit intensity values to 16 bit intensity values
%
% NOTE: word_array_16_bit values read from storage are only
% 12 bit values with 4 bit padding. Matlab's demosaic()
% function expects to see 16 bit values scaled properly.
scaled_word_array_16_bit = word_array_16_bit * 16;
% reshape the inline data into a frame buffer matrix
rc_matrix = reshape(scaled_word_array_16_bit, [width, height]);
% transpose matrix
rc_matrix_transpose = rc_matrix.';
% demosaic the bayer matrix into an rgb bitmap representation
demosaic_img = demosaic(rc_matrix_transpose, 'rggb');
% display rgb_image
imshow(demosaic_img);
% cleanup
fclose(fd);

Answers (1)

Benjamin Kraus
Benjamin Kraus on 22 Feb 2023
Edited: Benjamin Kraus on 22 Feb 2023
I can't think of any operation that can scale and transpose the data simultaneously, short of writing your own MEX function, which probably wouldn't make much difference in performance (or could be slower). I also can't think of a way to avoid transposing the data, short reading the data in a different order or adding a for-loop, but I think that would make the read operation less efficient. My guess is your current code is probably about as good as you are going to get.
MATLAB is column-major, and based on reading this code, it looks like the data is stored in a row-major order, so the transpose is adjusting for that difference. I suppose you could pre-allocate a matrix of the correct size, then replace the call to reshape, transpose, and your scaling with a for-loop that pulls one row of data from the file, rescales it, then updates one row of the pre-allocated matrix. My guess is that would be slower than what you have already, but for the sake of argument, this is roughly what I'm thinking:
word_array_16_bit = fread(fd, width*height, 'uint16=>uint16');
rc_matrix_transpose = zeros(height, width, 'uint16');
for r = 1:height
start = (r-1)*width+1;
stop = r*width;
rc_matrix_transpose(r,:) = word_array_16_bit(start:stop) * 16;
end
Is there some reason you don't want to have to transpose the data?

Categories

Find more on Resizing and Reshaping Matrices in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!