diff --git a/Ipol/paper/Algos/algoFinal.tex b/Ipol/paper/Algos/algoFinal.tex index e00575d34d19cd68088dcfc371fd44561ca9dc53..f62c8773520078396d71b66cbac9c2a2ecc66215 100644 --- a/Ipol/paper/Algos/algoFinal.tex +++ b/Ipol/paper/Algos/algoFinal.tex @@ -9,22 +9,23 @@ \SetKwData{dire}{$\vec{V}_E$} \SetKwData{dst}{$W_0$} \SetKwData{ath}{$\varepsilon$} -\SetKwData{on}{isExtending} +%\SetKwData{on}{isExtending} %\SetKwData{nb}{$n_E$} \SetKwData{side}{$side$} \SetKwData{index}{$I$} \SetKwData{ninter}{$n_I$} +\SetKwData{ntemp}{$n_J$} \SetKwData{niside}{$n_I[side]$} -%\SetKwData{nbin}{$N_{inter}$} +\SetKwData{ntside}{$n_J[side]$} \SetKwData{imax}{$N_I$} \SetKwData{gdiff}{$\delta_G$} -\SetKwData{bsth}{$\mu$} +\SetKwData{bsth}{$\mu_{prev}$} \SetKwData{nb}{$n$} \SetKwData{pinchcount}{$n_P$} \SetKwData{pinchdelay}{$N_P$} \SetKwData{adsdelay}{$N_a$} \SetKwData{devang}{$\theta_{dev}$} -\SetKwData{added}{added} +\SetKwData{added}{$added$} \SetKwData{trial}{$i$} \SetKwData{half}{$\frac{1}{2}$} @@ -38,11 +39,12 @@ \SetKwFunction{getads}{getAdaptiveDirectionalScanner} \SetKwFunction{fscan}{firstScan} \SetKwFunction{size}{size} +\SetKwFunction{max}{max} \SetKwFunction{nscan}{nextScan} \SetKwFunction{locmax}{localMax} -\SetKwFunction{grad}{gradient} -\SetKwFunction{bsinit}{initializeBS} +\SetKwFunction{bsinit}{initializeBlurredSegment} \SetKwFunction{addpt}{addPoint} +\SetKwFunction{rempt}{removePoint} \SetKwFunction{thickness}{thickness} \SetKwFunction{setath}{setMaxThickness} \SetKwFunction{ang}{angle} @@ -57,54 +59,67 @@ \bs \takes $\emptyset$\; \dirn \takes \ortho(\dsd, \dire) -\Comment*{Gets test gradient direction - \dirn $\perp$ \dsd, \dirn$\cdot$\dire $>$ 0} -\ds \takes \getads (\dsc, \dsd, \dst) \Comment*{Gets an ADS from input scan} +\Comment*{Gets test gradient direction: + \dirn $\perp$ \dsd, \dirn$\cdot$\dire $> 0$} +\ds \takes \getads (\dsc, \dsd, \dst) \Comment*{Gets an ADS from input scan.} \scan \takes \fscan (\ds)\; \index \takes \locmax (\scan, \gmap, \gdiff, \vmap, \dirn) -\Comment*{Gets index of pixels with oriented gradient local max} -\If{\size(\index) $\neq$ 0}{ - \bs \takes \bsinit (\scan$[$\index$[$0$]]$, \ath) +\Comment*{Gets index of pixels with oriented gradient local max.} - \nb \takes 0\; - \pinchcount \takes 0\; - \ninter \takes (0, 0)\; - \While{\ninter $\neq$ (\imax, \imax)}{ - \nb \takes \nb + 1\; +\If{\size(\index) $\neq 0$}{ + \nb \takes $0$, + \pinchcount \takes $0$\; + \ninter \takes $(0, 0)$, + \ntemp \takes $(0, 0)$\; + \bsinit (\bs, \scan$[$\index$[0]]$, \ath)\; + \While{\ninter $-$ \ntemp $\neq$ (\imax, \imax)}{ + \nb \takes \nb $+$ $1$\; \bsth \takes \thickness(\bs)\; \If{\pinchcount = \pinchdelay}{ - \setath (\bs, \thickness(\bs + \half))\; + \setath (\bs, \max (\ath, \thickness(\bs) + \half))\; } \If{\nb $>$ \adsdelay}{ - \If{\nb = \adsdelay + 1 and \angle(\dir(\bs),\dsd) $>$ \devang}{ - \on \takes (false, false) \Comment*{Too large deviation} + \If{\nb = \adsdelay $+$ $1$ and \angle(\dir(\bs),\dsd) $>$ \devang}{ + \niside \takes \ntside $+$ (\imax, \imax) + \Comment*{Too large deviation} } \alignds(\ds,\centerline(\bs)) \Comment*{Aligns scan stripe on blurred segment.} } \ForEach{\side}{ - \If{\niside $\leq$ \imax}{ + \If{\niside $-$ \ntside $\leq$ \imax}{ \scan \takes \nscan (\ds, \side)\; \index \takes \locmax (\scan, \gmap, \gdiff, \vmap, \dirn)\; - \trial \takes false\; - \added \takes false\; - \While{\added = false and \trial $<$ \size(\index)}{ + \trial \takes $0$\; + \added \takes $false$\; + \While{\added $=$ false and \trial $<$ \size(\index)}{ \added \takes \addpt (\bs, \scan$[$\index$[$\trial$]]$) - \Comment*{Tests BS extension} - \trial \takes \trial + 1\; + \Comment*{Tries blurred segment extension.} + \trial \takes \trial $+$ $1$\; } - \pinchcount \takes \pinchcount + 1\; + \pinchcount \takes \pinchcount $+$ $1$\; \eIf{\added}{ \If{\pinchcount $<$ \pinchdelay and \bsth $<$ \thickness(\bs)}{ - \pinchcount \takes 0 \Comment*{Not yet stabilized.} + \pinchcount \takes $0$ \Comment*{Not yet stabilized.} + } + \If{\niside $\neq$ $0$}{ + \ntside \takes \ntside $+$ $1$\; + \If{\niside $=$ \ntside}{ + \ntside \takes $0$, + \niside \takes $0$ + \Comment*{Validates last added points.} + } } - \niside \takes 0 \Comment*{Resets fail count.} }{ - \niside \takes \niside + 1 \Comment*{Increments fail count.} + \niside \takes \niside $+$ $1$ \Comment*{Increments fail count.} } } } } + \ForEach{\side}{ + \rempt (\bs, \side, \ntside) + \Comment*{Removes not yet validated points.} + } } \label{algo:final} \end{algorithm} diff --git a/Ipol/paper/Algos/algoInitial.tex b/Ipol/paper/Algos/algoInitial.tex index e3371f436a78693ee431806deb11548a7c1b1d30..9bf3e43f1796781ecb51f31c214842840f810229 100644 --- a/Ipol/paper/Algos/algoInitial.tex +++ b/Ipol/paper/Algos/algoInitial.tex @@ -5,9 +5,9 @@ \SetKwData{takes}{$\leftarrow$} \SetKwData{is}{$P_1P_2$} \SetKwData{ath}{$\varepsilon$} -\SetKwData{on}{isExtending} -\SetKwData{nb}{$n_E$} -\SetKwData{side}{side} +%\SetKwData{on}{isExtending} +\SetKwData{nb}{$n$} +\SetKwData{side}{$side$} \SetKwData{index}{$i$} \SetKwData{ninter}{$n_I$} \SetKwData{niside}{$n_I[side]$} @@ -23,9 +23,9 @@ \SetKwFunction{getds}{getDirectionalScanner} \SetKwFunction{fscan}{firstScan} \SetKwFunction{nscan}{nextScan} -\SetKwFunction{largest}{atLargest} +\SetKwFunction{largest}{atLargestGradient} \SetKwFunction{grad}{gradient} -\SetKwFunction{bsinit}{initializeBS} +\SetKwFunction{bsinit}{initializeBlurredSegment} \SetKwFunction{addpt}{addPoint} \Input{gradient magnitude map \gmap, @@ -33,32 +33,29 @@ \Output{a detected blurred segment \bs} \bs \takes $\emptyset$\; -\ds \takes \getds (\is) -\Comment*{Gets a DS from input segment.} +\ds \takes \getds (\is) \Comment*{Gets a DS from input segment.} \scan \takes \fscan (\ds)\; \index \takes \largest (\scan, \gmap, \gmin) \Comment*{Gets index of pixel with max gradient.} \If{\grad(\gmap$[$\scan$[$\index$]]$) $\geq$ \gmin}{ - \bs \takes \bsinit (\scan$[$\index$]$, \ath) - - \nb \takes 0\; - \ninter \takes (0, 0) - \Comment*{One counter for each side.} - \While{\ninter $\neq$ (\imax, \imax) and \nb $\neq$ \nmax - \Comment*{No more than \nmax extent.}}{ + \nb \takes \nmax + \Comment*{Limits the blurred segment extension.} + \ninter \takes ($0$, $0$) \Comment*{One counter for each side.} + \bsinit (\bs, \scan$[$\index$]$, \ath)\; + \While{\ninter $\neq$ (\imax, \imax) and \nb $\neq$ $0$}{ \ForEach{\side}{ \If{\niside $\leq$ \imax}{ \scan \takes \nscan (\ds, \side)\; \index \takes \largest (\scan, \gmap)\; \eIf{\addpt (\bs, \scan$[$\index$]$) \Comment*{Tests BS extension.}}{ - \niside \takes 0 \Comment*{Resets fail count.} + \niside \takes $0$ \Comment*{Resets fail count.} }{ - \niside \takes \niside + 1 + \niside \takes \niside $+$ $1$ \Comment*{Increments fail count.} } } } - \nb \takes \nb + 1 + \nb \takes \nb $-$ $1$ \Comment*{Increments extension count.} } } diff --git a/Ipol/paper/Algos/algoSingle.tex b/Ipol/paper/Algos/algoSingle.tex new file mode 100644 index 0000000000000000000000000000000000000000..ff7163bfb97bf2d008cdcdbcb5bebc4f9ff33f5a --- /dev/null +++ b/Ipol/paper/Algos/algoSingle.tex @@ -0,0 +1,58 @@ +\begin{algorithm}[!htbp] +\caption{detectBlurredSegment} +\DontPrintSemicolon + +\SetKwData{takes}{$\leftarrow$} +\SetKwData{is}{$P_1P_2$} +\SetKwData{ath}{$\varepsilon$} +\SetKwData{minsize}{$S_{min}$} +\SetKwData{crossang}{$\alpha_{min}$} +\SetKwData{vecbs}{$\vec{D}$} +\SetKwData{nb}{$n$} +\SetKwData{ang}{$angle$} +\SetKwData{bsstart}{$P$} +\SetKwData{dire}{$\vec{V}_E$} +\SetKwData{centerpt}{$C$} +%\SetKwData{imax}{$N_I$} + +\SetKwArray{gmap}{$\mathcal{G}$} +\SetKwArray{vmap}{$\mathcal{V}$} +\SetKwArray{bs}{$\mathcal{B}$} + +\SetKwFunction{fasttrack}{fastTrack} +\SetKwFunction{finetrack}{fineTrack} +\SetKwData{size}{$size$} +\SetKwData{extent}{$extent$} +\SetKwFunction{dir}{direction} +\SetKwFunction{startpt}{startPoint} +\SetKwFunction{centerline}{centerLine} + +\Input{gradient magnitude map \gmap, gradient orientation map \vmap, + input segment \is, assigned thickness \ath} +\Output{a detected blurred segment \bs} + +\bs \takes \fasttrack (\gmap, \is, \ath) +\Comment*{Gets rough initial solution.} +\eIf{\size (\bs) $<$ \minsize}{ + \bs \takes $\emptyset$ \Comment*{Not enough points.} +}{ + \eIf{\size(\bs) $<$ \extent(\bs) $/$ $2$}{ + \bs \takes $\emptyset$ \Comment*{Not dense enough.} + }{ + \vecbs \takes \dir(\bs)\; + \eIf{\ang (\vecbs, \is) $<$ \crossang}{ + \bs \takes $\emptyset$ \Comment*{BS direction too close to \is.} + }{ + \bsstart \takes \startpt (\bs)\; + \dire \takes \vmap $[$ \bsstart $]$\; + \centerpt \takes \centerline (\bs) $\cup$ \is\; + \bs \takes \finetrack (\gmap, \vmap, \centerpt, \vecbs, $2$ \ath, \ath, \dire) + \Comment*{Runs fine tracking.} + \If{\size (\bs) $<$ \minsize}{ + \bs \takes $\emptyset$ \Comment*{Not enough points.} + } + } + } +} +\label{algo:single} +\end{algorithm} diff --git a/Ipol/paper/algos.tex b/Ipol/paper/algos.tex index d9e2119932bd6aea44eca0238c4436839d9910be..8867825045b5405db4335eef67bb0b0ba1fc099a 100644 --- a/Ipol/paper/algos.tex +++ b/Ipol/paper/algos.tex @@ -19,11 +19,18 @@ supervised control tasks. The input of this step is a line segment, the input stroke, and the output is a blurred segment crossed by the input stroke. -The method is depicted in algorithm~\ref{algo:initial}. +The process is detailed in algorithm~\ref{algo:initial}. +Candidate points for blurred segment extension are selected on the basis +of maximal gradient magnitude. +Because the goal is to provide an initial incomplete solution, the blurred +segment is bounded to a small size. +Further extension is considered as useless. +On each side, the process stops after a fixed amount of successive extension +fails. \input{Algos/algoInitial} -Three parameters are used in this step : +Three parameters are used in this step: a minimal gradient magnitude $G_{min}$ to select candidates, a maximal extent $N_E$ of the blurred segment, and a maximal count $N_I$ of successive extent fails. @@ -34,24 +41,45 @@ that can be adjusted according to the application context. \subsection{Fine tracking step of single extraction} The input of this step is the direction of the rough blurred segment -provided by the initial detection, and the output is a finer blurred segment -obtained by -\begin{itemize} -\item more candidates based on local gradient magnitude, -\item constrained gradient orientation when selecting candidates, -\item adaptation of the scan stripe direction, -\item pinch of assigned thickness to the detected blurred segment thickness. -\end{itemize} -The method is depicted in algorithm~\ref{algo:final}. +provided by the initial detection, and the output is a refined solution. +The process is detailed in algorithm~\ref{algo:final}. +A new blurred segment is created and extended, but this time, all local +maxima of gradient magnitude found in the scan are tested untill a valid +one is found. Moreover the gradient orientation is checked when selecting +candidate points, using a rather strict maximal deviation value. +In order to avoid early stops when the detected segment escapes from the +scan stripe, the directional scanner is aligned on the blurred segment +center line at each step. This alignment is only performed after a +predefined number of steps when the blurred segment direction gets +stable enough. \input{Algos/algoFinal} -Three new parameters are used in this step : +Moreover when the growing segment stops thickenning, the assigned maximal +thickness of the recognition algorithm is pinched to a near value to +the observed thickness. This pinch procedure avoids further inclusion of +outliers, in particular when sharper edges lye quite close to or even across +(shadows) the detected blurred segment. +The half pixel ratio allows to take into account all the possible directions +of the blurred segment inferred from current configuration. +Finally, when any extension fail occurs, the amount of later successful +extensions must coincide to the fail count to validate these points. +This condition helps to detect more accurate segment ends. + +Three new parameters are used in this step: a gradient height $\delta_G$ to discriminate local gradient maxima, a minimal count $N_P$ of successive extents without blurred segment thickening, and a minimal extent $N_A$ before recentering the scan stripe. Nominal values are proposed for all of them. +\subsection{Single blurred segment extraction} + +The blurred segment extraction calls the initial detection, then the fine +tracking steps and applies optional validation tests to the output segment. +It is detailed in algorithm~/ref{algo:single}. + +\input{Algos/algoSingle} + \subsection{Multiple extraction} \subsection{Automatic extraction}