0001 %IMAGE2SPECTRUM - Converts a photograph of refracted light (a spectrograph)
0002 %                 into a column array or a matrix of three column arrays of
0003 %                 data points that represent the light's spectrum (a
0004 %                 spectrogram).
0005 %
0006 % It's not necessary to use every row of a spectrograph to derive the
0007 % spectrogram. Although every column is always used. To specify a horizontal
0008 % slice (region of interest), use the optional argument roi.
0009 %
0010 % Syntax:  Z = image2spectrum(img, color, roi)
0011 %
0012 % Inputs:
0013 %    img   - an image matrix or an image's filename.
0014 %    color - valid arguments are 'gray' and 'rgb'. If 'rgb' is given then Z
0015 %            is returned as a matrix of three column vectors, with the
0016 %            columns being separate red, green, and blue spectrograms. If
0017 %            'gray' is given, a single spectrogram that is the average of the
0018 %            red, green and blue spectrograms is returned. If a grayscale
0019 %            image is given, while color is set to 'rgb' a gray spectrogram
0020 %            is still returned. default is 'rgb'
0021 %    roi   - region of interest of spectrograph to process.
0022 %            roi(1), y0 is the first row of the horizontal slice. default: 1.
0023 %            roi(2), h is the height of the region, the final row is y0+h-1.
0024 %            default: image height.
0025 %
0026 % Outputs:
0027 %    Z - a column array or a matrix of three column arrays of data points
0028 %        that represent the photographed light's spectrum (a spectrogram).
0029 %
0030 % Example:
0031 %    Z = image2spectrum('path/filename');
0032 %    h=100; y0=(size(I,1)-h)/2; Z=image2spectrum(I, 'gray', [y0, h]);
0033 %
0034 % Other m-files required: frame_read
0035 % Subfunctions: none
0036 % MAT-files required: none
0037 %
0038 % See also: WAVELENGTH_CALIBRATE
0039 %
0040 % Author: Jonathan Thomson
0041 % Work:
0042 % email:
0043 % Website: http://jethomson.wordpress.com
0044 %
0045 
0046 function Z = image2spectrum(img, color, roi)
0047 
0048     if (nargin < 1 || nargin > 3 || isempty(img))
0049         usage('image2spectrum(img, color, roi)');
0050     end
0051 
0052     if (ischar(img) == 1)
0053         I = frame_read(img);
0054     else
0055         I = double(img);
0056     end
0057 
0058     if (~exist('color','var') || isempty(color))
0059         color = 'rgb';
0060     end
0061 
0062     if (~exist('roi','var') || isempty(roi))
0063         roi = [0, 0];
0064     end
0065 
0066 
0067 
0068     if (roi(1) == 0)
0069         roi(1) = 1;
0070     end
0071 
0072     if (length(roi) < 2 || roi(2) == 0)
0073         roi(2) = size(I,1);
0074     end
0075 
0076     y0 = roi(1);
0077     h = roi(2);
0078 
0079     S = I(y0:y0+(h-1), :, :);
0080 
0081     % The averaging function must be explicitly told to average columnwise
0082     % by being passed 1 as the second argument. This prevents incorrectly
0083     % averaging a vector when h is 1.
0084     % If img is the result of averaging many images then mean and median produce
0085     % nearly the same result. median should reduce the effect of hot pixels
0086     % better than mean. However, if img is a single image then mean produces a
0087     % a more accurate spectrum.
0088     Z = mean(S, 1);
0089     %Z = median(S, 1); % ignores hot pixels.
0090 
0091     Z = reshape(Z, [size(Z, 2), size(Z, 3)]); %from 1xwidthx3 to widthx3
0092 
0093     if (strcmpi(color,'gray') || strcmpi(color,'grey'))
0094         Z = mean(Z, 2);
0095     end
0096 
0097 end