Merge pull request #1196 from tucna:fuzzy_documentation
commit
38dd47cf40
17 changed files with 373 additions and 60 deletions
@ -0,0 +1,60 @@ |
||||
Filtering using F-transform {#tutorial_fuzzy_filtering} |
||||
============= |
||||
|
||||
Goal |
||||
==== |
||||
This tutorial demonstrates to you how to use F-transform for image filtering. You will see: |
||||
|
||||
- basic theory behind, |
||||
- illustration of different settings. |
||||
|
||||
Fuzzy transform application |
||||
==== |
||||
As I shown in previous tutorial, F-transform is a tool of fuzzy mathematics highly usable in image processing. Let me rewrite the formula using kernel \f$g\f$ introduced before as well: |
||||
|
||||
\f[ |
||||
F^0_{kl}=\frac{\sum_{x=0}^{2h+1}\sum_{y=0}^{2h+1} \iota_{kl}(x,y) g(x,y)}{\sum_{x=0}^{2h+1}\sum_{y=0}^{2h+1} g(x,y)}, |
||||
\f] |
||||
|
||||
where \f$\iota_{kl} \subset I\f$ centered to pixel \f$(k \cdot h,l \cdot h)\f$ and \f$g\f$ is a kernel. More details can be found in related papers. |
||||
|
||||
Code |
||||
==== |
||||
@include fuzzy/samples/fuzzy_filtering.cpp |
||||
|
||||
Explanation |
||||
==== |
||||
Image filtering changes input in a defined way to enhance or simply change some concrete feature. Let me demonstrate some simple blur. |
||||
|
||||
As a first step, we load input image. |
||||
|
||||
@code{.cpp} |
||||
// Input image |
||||
Mat I = imread("input.png"); |
||||
@endcode |
||||
|
||||
Following the F-transform formula, we must specify a kernel. |
||||
|
||||
@code{.cpp} |
||||
// Kernel cretion |
||||
Mat kernel1, kernel2; |
||||
|
||||
ft::createKernel(ft::LINEAR, 3, kernel1, 3); |
||||
ft::createKernel(ft::LINEAR, 100, kernel2, 3); |
||||
@endcode |
||||
|
||||
> So now, we have two kernels that differ in `radius`. Bigger radius leads to bigger blur. |
||||
|
||||
The filtering itself is applied as shown below. |
||||
|
||||
@code{.cpp} |
||||
// Filtering |
||||
Mat output1, output2; |
||||
|
||||
ft::filter(I, kernel1, output1); |
||||
ft::filter(I, kernel2, output2); |
||||
@endcode |
||||
|
||||
Output images look as follows. |
||||
|
||||
![input, output1 (radius 3), output2 (radius 100)](images/fuzzy_filt_output.jpg) |
After Width: | Height: | Size: 66 KiB |
@ -0,0 +1,26 @@ |
||||
Fuzzy image processing tutorials {#tutorial_fuzzy} |
||||
============================================================= |
||||
|
||||
- @subpage tutorial_fuzzy_theory |
||||
|
||||
_Compatibility:_ \> OpenCV 3.2.0 |
||||
|
||||
_Author:_ Pavel Vlasanek |
||||
|
||||
You will learn basics about fuzzy mathematics namely F-transform of certain degree. |
||||
|
||||
- @subpage tutorial_fuzzy_inpainting |
||||
|
||||
_Compatibility:_ \> OpenCV 3.2.0 |
||||
|
||||
_Author:_ Pavel Vlasanek |
||||
|
||||
You will learn how to use fuzzy mathematics in task of image inpainting. |
||||
|
||||
- @subpage tutorial_fuzzy_filtering |
||||
|
||||
_Compatibility:_ \> OpenCV 3.2.0 |
||||
|
||||
_Author:_ Pavel Vlasanek |
||||
|
||||
You will learn how to use fuzzy mathematics in task of image filtering. |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 82 KiB |
@ -0,0 +1,104 @@ |
||||
Inpainting using F-transform {#tutorial_fuzzy_inpainting} |
||||
============= |
||||
|
||||
Goal |
||||
==== |
||||
In this tutorial, you will learn how image inpainting using F-transform works. It consists in: |
||||
|
||||
- basic theory behind, |
||||
- three different algorithms. |
||||
|
||||
Introduction |
||||
==== |
||||
The goal of this tutorial is to show that the inverse F-transform can be used for image reconstruction. By the image reconstruction, we mean a reconstruction of a corrupted image where corruption is everything that the original image does not include. It can be noise, text, scratch, etc. Proposal is to solve the problem of reconstruction with the help of an approximation technique. This means that we will be looking for an approximating image which is close to the given one and at the same time, does not contain what we recognize as the corruption. This task is called _image inpainting_. |
||||
|
||||
Fuzzy transform application |
||||
==== |
||||
As I shown in previous tutorial, F-transform is a tool of fuzzy mathematics highly usable in image processing. Let me rewrite the formula using kernel \f$g\f$ introduced before as well: |
||||
|
||||
\f[ |
||||
F^0_{kl}=\frac{\sum_{x=0}^{2h+1}\sum_{y=0}^{2h+1} \iota_{kl}(x,y) g(x,y)}{\sum_{x=0}^{2h+1}\sum_{y=0}^{2h+1} g(x,y)}, |
||||
\f] |
||||
|
||||
where \f$\iota_{kl} \subset I\f$ centered to pixel \f$(k \cdot h,l \cdot h)\f$ and \f$g\f$ is a kernel. For purpose of image processing, a binary mask \f$S\f$ is used such as |
||||
|
||||
\f[ |
||||
g^s_{kl} = g \circ s_{kl} |
||||
\f] |
||||
|
||||
where \f$s_{k,l} \subset S\f$. Subarea \f$s\f$ of mask \f$S\f$ corresponds with subarea \f$\iota\f$ of image \f$I\f$. Operator \f$\circ\f$ is element-wise matrix multiplication (Hadamard product). Formula is updated to |
||||
|
||||
\f[ |
||||
F^0_{kl}=\frac{\sum_{x=0}^{2h+1}\sum_{y=0}^{2h+1} \iota_{kl}(x,y) g^s(x,y)}{\sum_{x=0}^{2h+1}\sum_{y=0}^{2h+1} g^s(x,y)}. |
||||
\f] |
||||
|
||||
More details can be found in related papers. |
||||
|
||||
Code |
||||
==== |
||||
|
||||
@include fuzzy/samples/fuzzy_inpainting.cpp |
||||
|
||||
Explanation |
||||
==== |
||||
The sample below demonstrates the usage of image inpainting. Three artificial images are created using the same input and three different type of corruption. In the real life usage, the input image will be already presented but here we created it by ourselves. |
||||
|
||||
First of all, we must load our image and three masks used for artificial damage creation. |
||||
|
||||
@code{.cpp} |
||||
// Input image |
||||
Mat I = imread("input.png"); |
||||
|
||||
// Various masks |
||||
Mat mask1 = imread("mask1.png", IMREAD_GRAYSCALE); |
||||
Mat mask2 = imread("mask2.png", IMREAD_GRAYSCALE); |
||||
Mat mask3 = imread("mask3.png", IMREAD_GRAYSCALE); |
||||
@endcode |
||||
|
||||
> See that mask must be loaded as `IMREAD_GRAYSCALE`. |
||||
|
||||
In the next step, the masks are used for damaging our input image. |
||||
|
||||
@code{.cpp} |
||||
// Apply the damage |
||||
Mat input1, input2, input3; |
||||
|
||||
I.copyTo(input1, mask1); |
||||
I.copyTo(input2, mask2); |
||||
I.copyTo(input3, mask3); |
||||
@endcode |
||||
|
||||
Using the masks, we applied three different kind of corruption on the same input image. Here is the result. |
||||
|
||||
![input1, input2 and input3](images/fuzzy_inp_input.jpg) |
||||
|
||||
> Do not forget that in real life usage, images `input1`, `input2` and `input3` are created naturaly and used as the input directly. |
||||
|
||||
Declaration of output images follows. In the following lines, the method of inpainting is applied. Let me explain three different algorithms one by one. |
||||
|
||||
First of them is `ONE_STEP`. |
||||
|
||||
@code{.cpp} |
||||
ft::inpaint(input1, mask1, output1, 2, ft::LINEAR, ft::ONE_STEP); |
||||
@endcode |
||||
|
||||
The `ONE_STEP` algorithm simply compute direct F-transform ignoring damaged parts using kernel with radius `2` (as specified in the method calling). Inverse F-transform fill up the missing area using values from the components nearby. It is up to you to choose radius which is big enough. |
||||
|
||||
Second is `MULTI_STEP`. |
||||
|
||||
@code{.cpp} |
||||
ft::inpaint(input2, mask2, output2, 2, ft::LINEAR, ft::MULTI_STEP); |
||||
ft::inpaint(input3, mask3, output3, 2, ft::LINEAR, ft::MULTI_STEP); |
||||
@endcode |
||||
|
||||
`MULTI_STEP` algorithm works in the same way but defined radius (`2` in this case) is automatically increased if it is found insufficient. If you want to fill up the hole and you are not sure how big radius you need, you can choose `MULTI_STEP` and let the computer decide. The lowest possible will be found. |
||||
|
||||
Last one is `ITERATIVE`. |
||||
|
||||
@code{.cpp} |
||||
ft::inpaint(input3, mask3, output4, 2, ft::LINEAR, ft::ITERATIVE); |
||||
@endcode |
||||
|
||||
Best choice in majority of cases is `ITERATIVE`. This way of processing use small radius of basic functions for small kind of damage and higher ones for bigger holes. |
||||
|
||||
![output1 (ONE_STEP), output2 (MULTI_STEP), output3 (MULTI_STEP), output4 (ITERATIVE)](images/fuzzy_inp_output.jpg) |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 35 KiB |
@ -0,0 +1,85 @@ |
||||
F-transform theory {#tutorial_fuzzy_theory} |
||||
============= |
||||
|
||||
Goal |
||||
==== |
||||
In this tutorial, the basic concept of fuzzy transform is presented. You will learn: |
||||
|
||||
- mathematic background, |
||||
- how to apply concept of fuzziness to image processing. |
||||
|
||||
The presented explanation demands knowledge of basic math. All related papers are cited and mostly accessible on https://www.researchgate.net/. |
||||
|
||||
Introduction |
||||
==== |
||||
In the last years, the theory of F-transforms has been intensively developed in many directions. In image processing, it has had successful applications in image compression and reduction, image fusion, edge detection and image reconstruction @cite Perf:FT @cite MSLP:cod-decod @cite Fusion:AFS12 @cite IPMU2012 @cite Perf:rec @cite vlavsanek2015patch. The F-transform is a technique that places a continuous/discrete function in correspondence with a finite vector of its F-transform components. In image processing, where images are identified by intensity functions of two arguments, the F-transform of the latter is given by a matrix of components. |
||||
|
||||
Let me introduce F-transform of a 2D grayscale image \f$I\f$ that is considered as a function \f$I:[0,M]\times [0,N]\to [0,255]\f$ where \f$[0,M]=\{0,1,2,\ldots,M\}; [0,N]=\{0,1,2,\ldots,N\}\f$. It is assumed that the image is defined at points (pixels) that belong to the set \f$P\f$, where \f$P=\{(x,y)\mid x=0,1,\ldots, M;y=0,1,\ldots, N\}\f$. |
||||
|
||||
Let \f$A_0, \dots ,A_m\f$ and \f$B_0, \dots ,B_n\f$ be basic functions, \f$A_0, \dots ,A_m : [0,M] \to [0, 1]\f$ be fuzzy partition of \f$[0,M]\f$ and \f$B_0, \dots ,B_n :[0,N]\to [0, 1]\f$ be fuzzy partition of \f$[0,N]\f$. Assume that the set of pixels \f$P\f$ is _sufficiently dense with respect to the chosen partitions_. This means that for all \f$k\in{0,\dots, m}(\exists x\in [0,M]) \ A_k(x)>0\f$, and for all \f$l\in{0,\dots, n}(\exists y\in [0,N])\ B_l(y)>0\f$. |
||||
|
||||
\f$F^0\f$-transform |
||||
==== |
||||
We say that the \f$m\times n\f$-matrix of real numbers \f$F^0_{mn}[I] = (F^0_{kl})\f$ is called _the (discrete) F-transform_ of \f$I\f$ with respect to \f$\{A_0, \dots,A_m\}\f$ and \f$\{B_0, \dots,B_n\}\f$ if for all \f$k=0,\dots,m,\ l=0,\dots,n\f$: |
||||
|
||||
\f[ |
||||
F^0_{kl}=\frac{\sum_{y=0}^{N}\sum_{x=0}^{M} I(x,y)A_k(x)B_l(y)}{\sum_{y=0}^{N}\sum_{x=0}^{M} A_k(x)B_l(y)}. |
||||
\f] |
||||
|
||||
The coefficients \f$F^0_{kl}\f$ are called _components_ of the \f$F^0\f$-transform. |
||||
|
||||
\f$F^1\f$-transform |
||||
==== |
||||
\f$F^1\f$-transform has been presented in @cite perfilieva2014differentiation. We say that matrix \f$F^1_{mn}[I] = (F^1_{kl}), k=0,\ldots, m, l=0,\ldots, n\f$, is the \f$F^1\f$-transform of \f$I\f$ with respect to \f$\{A_k\times B_l\mid k=0,\ldots, m, l=0,\ldots, n\}\f$, and \f$F^1_{kl}\f$ is the corresponding \f$F^1\f$-transform component. |
||||
|
||||
The \f$F^1\f$-transform components of \f$I\f$ are linear polynomials in the form |
||||
|
||||
\f[ |
||||
F^1_{kl}(x,y)= c^{00}_{kl} + c^{10}_{kl}(x-x_k) + c^{01}_{kl}(y-y_l), |
||||
\f] |
||||
|
||||
where the coefficients are given by |
||||
|
||||
\f[ |
||||
c_{kl}^{00} =\frac{\sum_{y=0}^{N}\sum_{x=0}^{M} I(x,y)A_k(x)B_l(y)}{\sum_{y=0}^{N}\sum_{x=0}^{M} A_k(x)B_l(y)}, \\ |
||||
c_{kl}^{10} =\frac{\sum_{y=0}^{N}\sum_{x=0}^{M} I(x,y)(x - x_k)A_k(x)B_l(y)}{\sum_{y=0}^{N}\sum_{x=0}^{M} (x - x_k)^2A_k(x)B_l(y)}, \\ |
||||
c_{kl}^{01} =\frac{\sum_{y=0}^{N}\sum_{x=0}^{M} I(x,y)(y - y_l)A_k(x)B_l(y)}{\sum_{y=0}^{N}\sum_{x=0}^{M} (y - y_l)^2A_k(x)B_l(y)}. |
||||
\f] |
||||
|
||||
Application to image processing |
||||
==== |
||||
The technique of F-transforms uses two steps: _direct and inverse_. The direct step is described in the previous section whereas the inverse is as follows |
||||
|
||||
\f[ |
||||
O(x,y)=\sum_{k=0}^{m}\sum_{l=0}^{n} F^d_{kl}A_k(x)B_l(y), |
||||
\f] |
||||
|
||||
where \f$O\f$ is the output (reconstructed) image and \f$d\f$ is F-transform degree. In fact, the algorithm computes the F-transform components of the input image \f$I\f$ and spreads the components afterwards to the size of \f$I\f$. For details see @cite Perf:rec. Application to image processing is possible to take from two different views. |
||||
|
||||
From pixel point of view |
||||
---- |
||||
The pixels are processed one by one in a way that appropriate basic functions are found for each of them. It will be exactly four, two in each direction. We need some helper structure in the memory for collecting their values. The values will be used in the nominator of the related fuzzy component. Implementation of this approach uses keyword `FL` as __fast__ processing (because of more optimizations) and __linear basic function__. |
||||
|
||||
![Pixel point of view with marked basic functions related to processed pixel.](images/fuzzy_pixel_view.jpg) |
||||
|
||||
From fuzzy component point of view |
||||
---- |
||||
In this way, image is divided to the regular areas. Each area is processed separately using kernel window. This approach benefits from easy to understand, matrix based processing with straight forward parallelization. |
||||
|
||||
![Fuzzy component point of view with marked basic functions related to processed area.](images/fuzzy_BF_view.jpg) |
||||
|
||||
This approach uses kernel \f$g\f$. Let us show linear case with radius \f$h = 2\f$ as an example. |
||||
|
||||
\f[ |
||||
A = (0, 0.5, 1, 0.5, 0) \\ |
||||
B^T = (0, 0.5, 1, 0.5, 0) \\ |
||||
g = AB^T=\left( |
||||
\begin{array}{ccccc} |
||||
0 & 0 & 0 & 0 & 0 \\ |
||||
0 & 0.25 & 0.5 & 0.25 & 0 \\ |
||||
0 & 0.5 & 1 & 0.5 & 0 \\ |
||||
0 & 0.25 & 0.5 & 0.25 & 0 \\ |
||||
0 & 0 & 0 & 0 & 0 \\ |
||||
\end{array} |
||||
\right) |
||||
\f] |
Loading…
Reference in new issue