Commit cc22d505 by Turnhout, M.C. van

parent 1d55fd6e
 function [amounts, atoRGB, imrgb] = clrdecon(dyes, imRGB) function [amounts, P, Q, R] = clrdecon(dyes, im) % dyes: 3by2 or 3by3 matrix with a column with RGB values for each dye if size(dyes, 2) < 3, dyes(3, 3) = 0; end % dye OD matrix: amount*nOD p = log(dyes + 1); % add one to avoid taking log(0) (which would be bad) % normalise: matrix M contains p-hat' or nOD' M = p; for r = 1:size(p, 2) % loop over rows (input colours) M(r, :) = M(r, :)/norm(p(r, :)); % divide row by its length end M = M % image OD imOD = log(imRGB + 1); amounts = zeros(size(im)); P = amounts; Q = P; R = P; % dye contributions: 3 by 1 column amounts = inv(M')*imOD' amounts = M'\imOD'; % is faster and more accurate in Matlab % dye OD columns: a*k A = -log( (dyes + 1)/256 ); % add one to avoid taking log(0) (which would be bad) if sum(dyes(:, 3)) < 1 % replace third colour by a perpendicluar one A(:, 3) = cross(A(:, 1), A(:, 2)); end % convert back to intensities atoRGB = zeros(3); for c = 1:3 % [amounts(1)*M(c, 1) amounts(3)*M(c, 3) amounts(3)*M(c, 3)] atoRGB(c, :) = exp(amounts'.*M(c, :)) - 1; % subtract one to scale back to 0-255 % normalise: matrix K contains k-hat' K = A; for c = 1:size(K, 2) K(:, c) = K(:, c)/norm(K(:, c)); end K = K for r = 1:size(im, 1) for c = 1:size(im, 2) % pixel RGB values: 3 by 1 column Ip = double(squeeze(im(r, c, :))); % pixel OD Ap = -log( (Ip + 1)/256 ); % dye contributions: 3 by 1 column % amounts = inv(K)*Ap ap = K\Ap; % is faster in Matlab amounts(r, c, :) = ap; % reconstruct pixels RGB contributions P(r, c, :) = 256*exp(-ap(1)*K(:, 1))-1; Q(r, c, :) = 256*exp(-ap(2)*K(:, 2))-1; R(r, c, :) = 256*exp(-ap(3)*K(:, 3))-1; end end imrgb = sum(atoRGB, 1); end \ No newline at end of file
 ... ... @@ -79,7 +79,7 @@ Which simply says that the total amount of light absorbed at a certain wavelengt Equation \ref{sumdyedis} can be written in matrix form as (see equation \ref{sumdyesRGB} for an example): \begin{align} \mat{K} & = \begin{bmatrix} \col{\hat{k}}_1 & \col{\hat{k}}_ 2 & \dots & \col{\hat{k}}_D\end{bmatrix},\; \col{a} = \begin{bmatrix} \hat{a}_1 \\ \hat{a}_ 2\\ \vdots \\ \hat{a}_D\end{bmatrix}\\ \mat{K} & = \begin{bmatrix} \col{\hat{k}}_1 & \col{\hat{k}}_ 2 & \dots & \col{\hat{k}}_D\end{bmatrix},\; \col{a} = \begin{bmatrix} \hat{a}_1 \\ \hat{a}_ 2\\ \vdots \\ \hat{a}_D\end{bmatrix} \label{Kna}\\ \mat{K}\col{\hat{a}} & = \col{A} \label{sumdyesmat} \end{align} Matrix $\mat{K}$ is composed of the $D$ columns with (normalized) absorption coefficients $\col{\hat{k}}$ put together side-by-side. Since each column $\col{\hat{k}}$ contains $N$ coefficients for $N$ wavelengths, the size of $\mat{K}$ is $N\times D$. The column $\hat{a}$ contains the $D$ dye amounts $\hat{a}_1$ through $\hat{a}_D$, and column $\col{A}$ contains the total (summed) absorption of the $D$ dyes for each of the $N$ wavelengths. ... ... @@ -102,7 +102,7 @@ When we use three wavelengths and label them, say, $R$, $G$, and $B$ and (thus) and equation \ref{sumdyesinv} comes out as: \begin{bmatrix}\hat{a}_1\\\hat{a}_2\\\hat{a}_3 \end{bmatrix} = \begin{bmatrix} \hat{k}_{R_1} & \hat{k}_{R_2} & k_{R_3} \\ \hat{k}_{G_1} & \hat{k}_{G_2} & \hat{k}_{G_3} \\ \hat{k}_{B_1} & \hat{k}_{B_2} & \hat{k}_{B_3}\end{bmatrix}^{-1}\cdot \begin{bmatrix}A_R\\A_G\\A_B \end{bmatrix} \begin{bmatrix}\hat{a}_1\\\hat{a}_2\\\hat{a}_3 \end{bmatrix} = \begin{bmatrix} \hat{k}_{R_1} & \hat{k}_{R_2} & k_{R_3} \\ \hat{k}_{G_1} & \hat{k}_{G_2} & \hat{k}_{G_3} \\ \hat{k}_{B_1} & \hat{k}_{B_2} & \hat{k}_{B_3}\end{bmatrix}^{-1}\cdot \begin{bmatrix}A_R\\A_G\\A_B \end{bmatrix} \label{sumdyesinvRGB} So when we know matrix $\mat{K}$ (and can calculate its inverse), and know the total amount of absorption for the three wavelengths $\col{A}$, we can calculate the contributions (amounts) of the three dyes $\hat{a}$. ... ... @@ -148,22 +148,53 @@ Further note that this is now an \textsl{approximation} of the exact optical den \label{Apixelcompare}} \end{figure} Finally note that we introduced $\col{\hat{A}}$ to distinguish this approximated absorbance from equation \ref{Apixel}. So that we will now also write Finally note that we introduced $\col{\hat{A}}$ to distinguish this approximated absorbance from equation \ref{Apixel}. When we convert approximated absorbances back to (estimated) pixel intensities, we can undo the effect of adding 1 for the log: \hat{\col{I}}_p = I_\mathrm{max} \hat{\col{T}} = I_\mathrm{max} \mathrm{e}^{-\col{\hat{A}}} \label{Ipixela} \hat{\col{I}}_p = I_\mathrm{max} \mathrm{e}^{-\col{A}} =\left(I_\mathrm{max} + 1\right) \mathrm{e}^{-\col{\hat{A}}} - 1 \label{Ipixela} for pixel values and transmission values that are calculated from the approximated absorbance $\col{\hat{A}}$. Since $\col{\hat{A}}$ is an underestimation of $\col{A}$ (figure \ref{Apixela}), $\hat{\col{T}}$ is an overestimation of $\col{T}$ in the conversion $\col{T} \rightarrow \hat{\col{A}} \rightarrow \hat{\col{T}}$ ($\text{RGB} \rightarrow \text{absorbance} \rightarrow \text{RGB}$). The conversion $\col{T} \rightarrow \col{A} \rightarrow\col{T}$ is reversible and exact (figure \ref{notlogzeroT}). \begin{figure}[h] \tiny \subfloat[\label{notlogzeroT}]{% \def\svgwidth{0.47\linewidth}\includesvg{../pics/notlogzeroT}}\hfill \subfloat[\label{notlogzerodT}]{% \def\svgwidth{0.47\linewidth}\includesvg{../pics/notlogzerodT}}\\ \caption{Comparison of the transmission (pixel intensities) calculated with the exact and approximated absorbance. With \textbf{(a)} transmission with exact absorbance (equation \ref{Ipixel}, solid blue) and transmission with the approximated absorbance (equation \ref{Ipixela}, dashed red) as a function of pixel value $I_p$ for an 8-bits image ($I_\mathrm{max} = 255$); and \textbf{(b)} the relative error as a function of pixel value $I_p$ for 8-bits (blue), 12-bits ($I_\mathrm{max} = 4095$, red) and 16-bits images ($I_\mathrm{max} = 65\,535$, yellow). \label{Ipixelcompare}} \end{figure} The 100\,\% error in figure \ref{notlogzerodT} may look worse than it is: it means that the original pixel value of 1 has become 2, and the error of about 10\,\% for a pixel value of 10 means that the converted pixel value is about 11. The dynamic range of the camera does affect this error, but not to any appreciable amount. \section{And the number of the counting shall be three} \subsection{Getting $\hat{k}$ from measurement} You cannot just derive the (normalized) absorption vector $\hat{k}$ for your dye(s) in RGB from first principles. You may be able to find values on the internet \cite{Landini2020} or presets in the ImageJ plugin \cite{Landini2004}, but these values also once had to be derived from raw' RGB values.\\ \noindent You first need to record the RGB values in an image with pure dye'. This can be a specifically prepared sample or a region in your image where you are yo that you are only looking at that single dye \cite{Landini2004,Landini2020}. From this column with RGB values of the dye, you can calculate the dyes (approximated) absorbance column: \col{\hat{A}}_d = -\ln \left(\frac{\col{I}_d + 1}{I_\mathrm{max}+1} \right) \label{Apixeld} The values in this column are the product of the amount of dye (a single number) and the (normalised) absorbance of the dye: $\hat{a}\hat{k}$. And therefore: \begin{align} l_d & = \sqrt{\hat{A}_R^2 + \hat{A}_G^2 + \hat{A}_B^2}\\ \col{\hat{k}}_d & = \frac{\col{\hat{A}}_d}{l_d} \label{kpixeld} \end{align} That is: the normalized column $\col{\hat{k}}$ equals the normalized column $\col{\hat{A}}$. \subsection{Dealing with (only) two dyes} Three shall be the number thou shalt count, and the number of the counting shall be three. \ No newline at end of file If you want to deconvolve in three colours', you will have to use three dyes. So when you only have two dyes in your images, you will have to come up' with a third one, just to fill $\mat{K}$ for the deconvolution. For the analysis, it is best when this invented third colour is perpendicular' to the other two colours. To find aperpendicular' colour, you can use the cross product: \col{k}_3 = \col{\hat{k}}_1 \times \col{\hat{k}}_2 = \begin{bmatrix} k_{G_1}k_{B_2} - k_{B_1}k_{G_2}\\ % Kb*kg - Kg*kb k_{B_1}k_{R_2} - k_{R_1}k_{B_2} \\ % Kr*kb - Kb*kr, k_{R_1}k_{G_2} - k_{G_1}k_{R_2} \end{bmatrix} %Kg*kr - Kr*kg Note that this column still needs to be normalized to $\col{\hat{k}}_3$. \subsection{Summary: colour deconvolution in RGB} So the general workflow may look like this \begin{itemize} \item Get the RGB values for the three dyes that you would like to have deconvolved in your image and put them in a column $\col{I}_d$ for each dye. \item Calculate the (approximated) optical density columns $\col{\hat{A}}_d$ of the three dyes from $I_d$ (equation \ref{Apixeld}). \item Normalise the $\col{\hat{A}}_d$ columns to find the columns with coefficients $\hat{k}_d$ for each dye (equation \ref{kpixeld}). \item Collect the three $\hat{k}_d$ columns in a matrix $\mat{K}$ (equations \ref{Kna}, \ref{sumdyesRGB}) and calculate its inverse $\mat{K}^{-1}$. \item Then for each pixel in the image \begin{itemize} \item Get the RGB values for the pixel and put them in a (temporary) column $\col{I}_p$. \item Calculate the (approximated) optical density column $\col{\hat{A}}_p$ of the pixel (equation \ref{Apixela}). \item Multiply $\mat{K}^{-1}$ with $\col{\hat{A}}_p$ to find the column with dye contributions $\hat{a}$ for this pixel (equations \ref{sumdyesinv}, \ref{sumdyesinvRGB}). \item For image reconstruction: calculate the approximated column with pixel RGB values $\hat{I}_p$ with $\hat{a}_p$ (equation \ref{Ipixela}). \end{itemize} \end{itemize}
 ... ... @@ -13,7 +13,7 @@ h = legend('$\col{A} = -\ln(I_p/255)$', '$\col{\hat{A}} = -\ln( (I_p+1)/256)$'); set(h, 'box', 'off') figure('defaultlinelinewidth', 2) loglog(Ip, 255*exp(-A(1, :)), Ip, 255*exp(-A(2, :)), '--') loglog(Ip, 255*exp(-A(1, :)), Ip, 256*exp(-A(2, :))-1, '--') ylim([1 1000]) xlabel('pixel intensity\,[-]') ylabel('transmission\,[-]') ... ... @@ -35,7 +35,7 @@ for d = 1:numel(DR) IP(d, 1:numel(ip)) = ip; dA(d, 1:numel(ip)) = A(2, :)./A(1, :); dT(d, 1:numel(ip)) = exp(-A(2, :))./exp(-A(1, :)); dT(d, 1:numel(ip)) = ((2^n)*exp(-A(2, :))-1)./((2^n-1)*exp(-A(1, :))); end figure('defaultlinelinewidth', 2) ... ...

861 Bytes

 \ No newline at end of file

3.55 KB

File deleted
 %% Creator: Inkscape inkscape 0.92.5, www.inkscape.org %% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010 %% Accompanies image file 'notlogzeroT.pdf' (pdf, eps, ps) %% %% To include the image in your LaTeX document, write %% \input{.pdf_tex} %% instead of %% \includegraphics{.pdf} %% To scale the image, write %% \def\svgwidth{} %% \input{.pdf_tex} %% instead of %% \includegraphics[width=]{.pdf} %% %% Images with a different path to the parent latex file can %% be accessed with the import' package (which may need to be %% installed) using %% \usepackage{import} %% in the preamble, and then including the image with %% \import{}{.pdf_tex} %% Alternatively, one can specify %% \graphicspath{{/}} %% %% For more information, please see info/svg-inkscape on CTAN: %% http://tug.ctan.org/tex-archive/info/svg-inkscape %% \begingroup% \makeatletter% \providecommand\color[2][]{% \errmessage{(Inkscape) Color is used for the text in Inkscape, but the package 'color.sty' is not loaded}% \renewcommand\color[2][]{}% }% \providecommand\transparent[1]{% \errmessage{(Inkscape) Transparency is used (non-zero) for the text in Inkscape, but the package 'transparent.sty' is not loaded}% \renewcommand\transparent[1]{}% }% \providecommand\rotatebox[2]{#2}% \newcommand*\fsize{\dimexpr\f@size pt\relax}% \newcommand*\lineheight[1]{\fontsize{\fsize}{#1\fsize}\selectfont}% \ifx\svgwidth\undefined% \setlength{\unitlength}{495.98342126bp}% \ifx\svgscale\undefined% \relax% \else% \setlength{\unitlength}{\unitlength * \real{\svgscale}}% \fi% \else% \setlength{\unitlength}{\svgwidth}% \fi% \global\let\svgwidth\undefined% \global\let\svgscale\undefined% \makeatother% \begin{picture}(1,0.79287731)% \lineheight{1}% \setlength\tabcolsep{0pt}% \put(0,0){\includegraphics[width=\unitlength,page=1]{notlogzeroT.pdf}}% \put(0.05650088,0.03427534){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^0$ \end{tabular}}}}% \put(0.35651091,0.03427534){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^1$ \end{tabular}}}}% \put(0.65652094,0.03427534){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^2$ \end{tabular}}}}% \put(0.95653096,0.03427534){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^3$ \end{tabular}}}}% \put(0,0){\includegraphics[width=\unitlength,page=2]{notlogzeroT.pdf}}% \put(0.02028125,0.06149802){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^0$ \end{tabular}}}}% \put(0.02028125,0.29811884){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^1$ \end{tabular}}}}% \put(0.02028125,0.53473965){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^2$ \end{tabular}}}}% \put(0.02028125,0.77136046){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^3$ \end{tabular}}}}% \put(0,0){\includegraphics[width=\unitlength,page=3]{notlogzeroT.pdf}}% \put(0.44401383,0){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} pixel intensity\,[-] \end{tabular}}}}% \put(0.02020027,0.33291905){\rotatebox{90}{\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} transmission\,[-] \end{tabular}}}}}% \put(0,0){\includegraphics[width=\unitlength,page=4]{notlogzeroT.pdf}}% \put(0.1492318,0.73736557){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $\col{T}$ \end{tabular}}}}% \put(0.1492318,0.70762647){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $\col{\hat{T}}$ \end{tabular}}}}% \put(0,0){\includegraphics[width=\unitlength,page=5]{notlogzeroT.pdf}}% \end{picture}% \endgroup%
This diff is collapsed.
File deleted
 %% Creator: Inkscape inkscape 0.92.5, www.inkscape.org %% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010 %% Accompanies image file 'notlogzerodT.pdf' (pdf, eps, ps) %% %% To include the image in your LaTeX document, write %% \input{.pdf_tex} %% instead of %% \includegraphics{.pdf} %% To scale the image, write %% \def\svgwidth{} %% \input{.pdf_tex} %% instead of %% \includegraphics[width=]{.pdf} %% %% Images with a different path to the parent latex file can %% be accessed with the import' package (which may need to be %% installed) using %% \usepackage{import} %% in the preamble, and then including the image with %% \import{}{.pdf_tex} %% Alternatively, one can specify %% \graphicspath{{/}} %% %% For more information, please see info/svg-inkscape on CTAN: %% http://tug.ctan.org/tex-archive/info/svg-inkscape %% \begingroup% \makeatletter% \providecommand\color[2][]{% \errmessage{(Inkscape) Color is used for the text in Inkscape, but the package 'color.sty' is not loaded}% \renewcommand\color[2][]{}% }% \providecommand\transparent[1]{% \errmessage{(Inkscape) Transparency is used (non-zero) for the text in Inkscape, but the package 'transparent.sty' is not loaded}% \renewcommand\transparent[1]{}% }% \providecommand\rotatebox[2]{#2}% \newcommand*\fsize{\dimexpr\f@size pt\relax}% \newcommand*\lineheight[1]{\fontsize{\fsize}{#1\fsize}\selectfont}% \ifx\svgwidth\undefined% \setlength{\unitlength}{495.43440126bp}% \ifx\svgscale\undefined% \relax% \else% \setlength{\unitlength}{\unitlength * \real{\svgscale}}% \fi% \else% \setlength{\unitlength}{\svgwidth}% \fi% \global\let\svgwidth\undefined% \global\let\svgscale\undefined% \makeatother% \begin{picture}(1,0.79056278)% \lineheight{1}% \setlength\tabcolsep{0pt}% \put(0,0){\includegraphics[width=\unitlength,page=1]{notlogzerodT.pdf}}% \put(0.05545533,0.03431332){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^0$ \end{tabular}}}}% \put(0.23566083,0.03431332){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^1$ \end{tabular}}}}% \put(0.41586632,0.03431332){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^2$ \end{tabular}}}}% \put(0.59607181,0.03431332){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^3$ \end{tabular}}}}% \put(0.7762773,0.03431332){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^4$ \end{tabular}}}}% \put(0.95648279,0.03431332){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $10^5$ \end{tabular}}}}% \put(0,0){\includegraphics[width=\unitlength,page=2]{notlogzerodT.pdf}}% \put(0.03939096,0.06560303){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} 1 \end{tabular}}}}% \put(0.02122508,0.20773285){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} 1.2 \end{tabular}}}}% \put(0.02122508,0.34986267){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} 1.4 \end{tabular}}}}% \put(0.02122508,0.49199248){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} 1.6 \end{tabular}}}}% \put(0.02122508,0.6341223){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} 1.8 \end{tabular}}}}% \put(0.03939096,0.77625211){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} 2 \end{tabular}}}}% \put(0,0){\includegraphics[width=\unitlength,page=3]{notlogzerodT.pdf}}% \put(0.44339771,0){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} pixel intensity\,[-] \end{tabular}}}}% \put(0.02113297,0.38505212){\rotatebox{90}{\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} $\col{\hat{T}}/ \col{T}$\,[-] \end{tabular}}}}}% \put(0,0){\includegraphics[width=\unitlength,page=4]{notlogzerodT.pdf}}% \put(0.88793285,0.74022999){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} 8-bits \end{tabular}}}}% \put(0.88793285,0.71253409){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} 12-bits \end{tabular}}}}% \put(0.88793285,0.68483819){\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l} 16-bits \end{tabular}}}}% \put(0,0){\includegraphics[width=\unitlength,page=5]{notlogzerodT.pdf}}% \end{picture}% \endgroup%
This diff is collapsed.
 % dye RGB matrix dyes = [255 0 0; % RGB stain 1 0 255 0; % RGB stain 2 0 0 255]; % RGB stain 3 % dye OD matrix: amount*nOD p = -log(dyes + 1) % add one to avoid taking log(0) (which would be bad) % normalise: matrix M contains p-hat' M = p; for r = 1:size(p, 2) M(r, :) = M(r, :)/norm(p(r, :)); end M = M % image RGB values: 3 by 1 column imRGB = [200; 100; 0]; % imRGB = [75 0 130]'; % dye OD column: a*k A = -log( (dyes + 1)/256 ) % add one to avoid taking log(0) (which would be bad) % image OD imOD = -log(imRGB + 1) % dye contributions: 3 by 1 column % amounts = inv(M)*imOD amounts = M\imOD % is faster in Matlab if sum(dyes(3, :)) < 1 % replace third colour by a perpendicluar one A(3, :) = cross(A(1, :), A(2, :)) end % convert back to intensities atoR = exp(-amounts'.*M(1, :)) - 1; atoG = exp(-amounts'.*M(2, :)) - 1; atoB = exp(-amounts'.*M(3, :)) - 1; % normalise: matrix K contains k-hat' K = A; for r = 1:size(K, 1) K(r, :) = K(r, :)/norm(A(r, :)); end K = K imrgb = [atoR(1) atoG(2) atoB(3)] % pixel RGB values: 3 by 1 column Ip = [200; 100; 0] atoRGB = zeros(3); for c = 1:3 atoRGB(c, :) = exp(-amounts'.*M(c, :)) - 1; end imrgb = sum(atoRGB, 1) % pixel OD Ap = -log( (Ip + 1)/256 ) % dye contributions: 3 by 1 column % amounts = inv(K)*Ap ap = K\Ap % is faster in Matlab a = [.65 .7 .29; .07 .99 .11; .27 .57 .78]; norm(a(1, :)) inv(a) % reconstruct pixels RGB value Ir = 256*exp(-Ap)-1
 clear all; close all; dyes = [75 0 130; % indigo' 255 255 0; % yellow 0 140 20]; % no idea... dyes = [255 255 0; % yellow 0 255 0]'; % green im = imread('pics/Flag_of_Jamaica.png'); dyes = eye(3) imRGB = [0 14 2]; % % dyes = 255*eye(3); % im = imread('pics/1330px_Rainbow_flag_12_colours_black_bordered.png'); [amounts, P, Q, R] = clrdecon(dyes, im); [amounts, atoRGB, imrgb] = clrdecon(dyes, imRGB) \ No newline at end of file figure imshow(im) figure imshow(P) figure imshow(Q) figure imshow(R) for d = 1:3 figure imagesc(amounts(:, :, d)) colormap(gray) colorbar end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!