Commit a385008e authored by Turnhout, M.C. van's avatar Turnhout, M.C. van
Browse files

move complementary Ruifrok to algebra

parent 581463c5
......@@ -172,19 +172,36 @@ That is: the normalized column $\col{\hat{k}}$ equals the normalized column $\co
\subsection{Dealing with (only) two dyes}
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.
If you want to deconvolve in three `channels' (`R', `G' and `B'), you will have to use three dyes: $\mat{K}$ \textsl{has} to be square. So when you only have contributions of two dyes in your images, you will have to `come up' with a third (complementary) 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 a`perpendicular' colour, you can use the cross product:
\subsubsection{Perpendicular absorption}
For computational reasons it is best when the absorption column of the complementary dye is `perpendicular' to those of other two dyes. To find a`perpendicular' absorption column, you can use the cross product:
\begin{equation}
\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
\col{\hat{A}}_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} \label{anglecross}%Kg*kr - Kr*kg
k_{R_1}k_{G_2} - k_{G_1}k_{R_2} \end{bmatrix} \label{k3cross}%Kg*kr - Kr*kg
\end{equation}
Note that this column still needs to be normalized to $\col{\hat{k}}_3$. Also note that you can find the angle between two columns $n$ and $m$ by taking the inverse cosine of the inner dot product of the two columns (when the columns are normalised):
\begin{equation}
\varphi_{nm} =\acos\left(\colt{\hat{k}}_n \cdot \col{\hat{k}}_m\right) \label{angledot}
\end{equation}
\subsubsection{`Normalised' channel absorption}
The Java code by Ruifrok that was adapted by Landini for the `colour deconvolution' ImageJ plugin \cite{Landini2004,Landini2020,Landini2020a} contained an alternative (otherwise undocumented) method to obtain a third complementary dye.
This method attempts to normalise total absorption of all three dyes across a channel for each of the R, G and B channels and sets channel absorption for the complementary dye to 0 when this is not possible:
\begin{equation}
\hat{A}_{n_3} = \begin{cases} \sqrt{1 - k_{n_1}^2 - k_{n_2}^2} & \text{~for~} k_{n_1}^2 + k_{n_2}^2 \leq 1 \\
0 & \text{~for~} k_{n_1}^2 + k_{n_2}^2 > 1\end{cases} \label{k3norm}
\end{equation}
In other words, this method attempts to normalise the \textsl{rows} in the absorption matrix. Note that this row normalisation is `undone' when we normalise this new complementary absorption \textsl{column} for the matrix $\mat{K}$ (as is wont and proper).
Because this is not a proper normalisation (it may not work, and it is undone in the \mat{K} matrix) as we do with the columns in $\mat{K}$, we will call this the `Ruifrok' complementary absorption column in order to minimise possible confusion.
\subsection{Summary: colour deconvolution in RGB}
So the general workflow may look like this
......
......@@ -188,7 +188,7 @@ For our current purposes, we cannot help the suboptimal angle between the flags
\caption{Absorption columns in 3D space. With \textbf{(a)} the yellow, green, black and complementary absorption columns (bold) and the (mutually perpendicular) `R', `G' and `B' columns: the three flag dyes (yellow, green, black) are not perpendicular in absorption and the complementary `dye' (magenta) is perpendicular in absorption to the yellow and green dyes; and \textbf{(b)} another example of the non-linear relationship between transmission (RGB) and absorption (dyes): dyes/colours that are perfectly perpendicular in RGB (i.e.\ red, green and blue) only have a mutual angle of about 6\,\degree\ in absorption. \label{arrowsfig}}
\end{figure}
To do so, we need to calculate the normalised cross product of the normalised yellow dye and green dye absorption columns (equation \ref{anglecross}):
To do so, we need to calculate the normalised cross product of the normalised yellow dye and green dye absorption columns (equation \ref{k3cross}):
\begin{align}
\col{\hat{A}}_c = \col{\hat{k}}_y \times \col{\hat{k}}_g & = \begin{bmatrix*}[r] -0.0769 \\ 0.9623 \\ -0.0343\end{bmatrix*} \label{Apcross}\\
\col{\hat{k}}_c = \frac{\col{\hat{A}}_c }{\abs{\col{\hat{A}}_c }} & = \begin{bmatrix*}[r] -0.0796 \\ 0.9962\\ -0.0355\end{bmatrix*}
......@@ -199,8 +199,8 @@ Note the negative absorption coefficients: this column represents `a dye' that p
\end{equation}
In other words: this third `dye colour' is not a real `colour' and cannot be (properly) represented in RGB space. It is a column that (precisely) covers the part of the 3D absorption space that is not covered by the other two columns, it is `the (absorption) remainder' for use in deconvolution.
\subsection{Deconvolution}
\subsection{Deconvolution}
We replace the third column in our $\mat{K}$ matrix with the complementary absorption column and calculate the new inverse:
\begin{align}
......@@ -256,14 +256,7 @@ Also note, finally, that the combination of 75\,\% yellow, 100\,\% green and 5 u
The Java code by Ruifrok that was adapted by Landini for the `colour deconvolution' ImageJ plugin \cite{Landini2004,Landini2020,Landini2020a} contained an alternative (otherwise undocumented) method to obtain a third complementary colour.
This third method attempts to normalise total absorption of all three dyes across a channel for each of the R, G and B channels and sets channel absorption to 0 when this is not possible:
\begin{equation}
\hat{A}_{c_n} = \begin{cases} \sqrt{1 - k_{y_n}^2 - k_{g_n}^2} & \text{~for~} k_{y_n}^2 + k_{g_n}^2 \leq 1 \\
0 & \text{~for~} k_{y_n}^2 + k_{g_n}^2 > 1\end{cases}
\end{equation}
In other words, this method attempts to normalise the \textsl{rows} in the absoption matrix. Note that this row normalisation is `undone' when we normalise this new third absorption \textsl{column} for the matrix $\mat{K}$ (as is wont and proper).\\
\noindent For our example, this would make the complementary third `Ruifrok' absorption column:
For our example, this complementary `Ruifrok' absorption column (equation \ref{k3norm}) is given by:
\begin{align}
\col{\hat{A}}_c = \begin{bmatrix*}[r] \sqrt{1 - 0.0007^2 - 0.9631^2} \\ \sqrt{1 - 0.0357^2 - 0.0860^2}\\0\end{bmatrix*} & = \begin{bmatrix*}[r] 0.2690 \\ 0.9957\\0\end{bmatrix*}\\
\col{\hat{k}}_c = \frac{\col{\hat{A}}_c }{\abs{\col{\hat{A}}_c }} & = \begin{bmatrix*}[r] 0.2609 \\ 0.9654 \\ 0\end{bmatrix*}
......@@ -273,11 +266,6 @@ This is not an `ideal perpendicular' column: the angles with yellow $\varphi_{yc
\col{\hat{R}}_c = 256\cdot \mathrm{e}^{\begin{bmatrix*}[r] 0.2609 \\ 0.9654\\ 0\end{bmatrix*} \cdot 1} - 1 = \begin{bmatrix*}[r] 196\\ 96 \\ 255 \end{bmatrix*} \label{flagJA2rRc}
\end{equation}
\subsection{Deconvolution and reconstruction}
This makes the new $\mat{K}$ matrix and its inverse come out as:
\begin{align}
\mat{K} & = \begin{bmatrix*}[r] 0.0007 & 0.9631 & 0.2609\\
......@@ -317,6 +305,8 @@ The black patches now consist of 80\,\% of the flags yellow dye (figures \ref{fl
But this combination also, results in `proper black' in the reconstructed flag (figure \ref{flagJA2rygc}).
\subsection{Two or three, colours or dyes?}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment