% Incorporate external sensor data into the ISET pipeline
% 
% This script builds the NHK sensor and uses it to generate the sensor data
% from an NHK sensor image. That is, first the sensor is customized such
% that images formed on the focal plane (the optical image) are captured by
% an NHK sensor. Next, an NHK TIF sensor image is read to generate the raw 
% sensor input (the optical image). Can we go back one more step and
% generate the scene?
% Kunal Ghosh and Hiroshi Shimamoto
% 
% This script illustrates how to voltage responses from a prototype sensor
% into ISET. 
%
% There are two steps to the process.  First, you establish the sensor
% parameters for the device under test.  This needs to be done only once.
% Then, you read a Matlab file containing the  sensor data and store it in
% the sensor structure.  This is done for each data set.
%
% After reading in the data, you can experiment with the image processing
% pipeline and use the ISET image evaluation tools.
%

% Initiate a sensor structure.  We use this structure to characterize the
% device under test (dut).  We  do this by creating a default sensor and
% then setting its properties to match the dut.
dut = sensorCreate;
dut = sensorSet(dut,'name','NHK');

% Each object represents wavelength sampling of various elements (filters,
% photodetector, so forth).  This information is stored in two the
% 'spectrum' slot of the object. This slot lists the wavelength sample
% values in nanometers
%   
wave = 400:10:700;
dut = sensorSet(dut,'wave',wave);

% For a sensor, the color and infrared filter transmissivities are stored in dut.color
%
%  dut.color.filterSpectra --  a matrix, nWaveSamples x nColorFilters, whose columns 
%    define the filter wavelength tranmissivities
%  dut.color.filterNames   --  a cell array with nColorFilters names
%    indicating the character of the filters.  The first character
%    of the filterName should be 'r','g','b','c','y','m'
%  dut.color.irFilter      -- a vector with nWaveSamples that defines the infrared
%    transmissivity.  This is usually initialized to all 1's, but many
%    cameras use infrared filters and this parameter may be important. 
%  
% To read the color filter data, you must have a spectral file that
% contains the information.  The file should be in the format defined by
% ieSaveSpectralFile.  
%
% Here we read the default RGB color filters in the ISET directory.  You
% will want to read your own data.
%
% If you know the curves for your sensor RGB values, you can save them in
% the proper format using the routine:
%   ieSaveSpectralFile
%
fname = fullfile(isetRootPath,'ISET-Data','sensor','RGB.mat');
colorFilters = vcReadSpectra(fname,wave);
dut = sensorSet(dut,'colorFilters',colorFilters);

% Now read an infrared filter
fname = fullfile(isetRootPath,'ISET-Data','sensor','infrared2.mat');
irFilter = vcReadSpectra(fname,wave);
dut = sensorSet(dut,'irFilter',irFilter);

% We define the spatial configuration of the color filters.
%

pattern_4x2 = ...
     [2, 1; 
     3, 2; 
     2, 3; 
    1, 2];
pattern_3x3 = ...
    [2, 1, 3; 
     3, 2, 1; 
     1, 3, 2];
 pattern_bayer = ...
     [2, 1;
     3, 2];

dut = sensorSet(dut,'cfapattern',pattern_4x2);

%  Set the pixel properties.
pixel = sensorGet(dut,'pixel');
pixel = pixelSet(pixel,'name','nhkPixel');

pixelSize = 4.2e-6;   
pixel = pixelSet(pixel,'sizeconstantfillfactor',[pixelSize,pixelSize]);

% Many other pixel parameters can be set (see pixelSet).  Here are a few
% examples.
fname = fullfile(isetRootPath,'ISET-Data','sensor','photodetector.mat');
pixelSpectralQE = vcReadSpectra(fname,wave);
pixel = pixelSet(pixel,'spectralQE',pixelSpectralQE);
pixel = pixelSet(pixel,'voltageSwing',1);

% Re-attach the pixel to the sensor
dut = sensorSet(dut,'pixel',pixel);

% Now you can display the device under test in the window.  Note that the
% description in the window matches the parameters you set above.
%
val = vcAddAndSelectObject('sensor',dut); sensorImageWindow;

% You can also set using additional scripting or through the window
% interface.  If you then wish to save the sensor, you can do so from the
% window (File | Save Sensor (ISA))
%
% or by just saving it from the command window by typing
% dut = vcGetObject('sensor'); objFullFileName = vcExportObject(dut);

%-------------------------------------------
% You only need to create the sensor profile (as above) once.  After it is
% saved, you can always load the stored image sensor array description.
% dut = load(objFullFileName);
% Then, to examine voltage data you just read a file that contains the 
% variable 'volts'.  These are stored in the structure, and the window is
% refreshed. For example, I stored some data in this file.

% If the data are in a tiff file, you can do this
%
% fName = 'C:\EE 362 Class\Project\8mc\8ma_macbeth.tif';
fName = 'C:\EE 362 Class\Project\8mc\czp_bayer.tif';
volts = double(imread(fName));
figure; imagesc(volts); colormap(gray)

pixel = sensorGet(dut,'pixel');
vSwing = pixelGet(pixel,'voltageSwing');
volts = vSwing*volts/max(volts(:)); 

% tmp = volts(1001:1800,1501:2500);
tmp = volts(601:1400,1631:2630);
dut = sensorSet(dut,'volts',tmp);
sensorGet(dut,'rows')
sensorGet(dut,'cols')

% If it is a Matlab file full of data, do this.
% fullName = 'dutData.mat';
% tmp = load(fullName,'volts');
% dut = sensorSet(dut,'volts',tmp.volts);

vcReplaceObject(dut,val); sensorImageWindow;

% ?where to change color pattern of the sensor?

% Call the custom demosaicing routine and generate the demosaiced image
vci = vcImageCreate;
vci = imageSet(vci,'demosaicMethod','nhkInter');
vci = nhkRender(vci,dut); % call the demosaicing script
vcReplaceObject(vci); vcimageWindow;

