Spacial resolution of wavelets. Providing higher detail on a particular part of the image
In this second chapter we will use the properties of wavelets we saw previously in order to
realize an image transmission format which allows for sending of an image with different levels
of details in different regions.
Spacial resolution of wavelet modes
In the previous chapter we saw how an image can be transformed into wavelet modes.
We also saw how we can apply consistently low-pass or high-pass filters so we can
change the global level of detail of the image. The low-pass
filters can be used for noise reduction or for data compression. The high-pass filters
can be used for the extraction of higher order features of the image such as edges.
In this chapter we will discuss more on the spacial resolution of the different modes \(s, x^i, y^i, d^i\).
We start with the the first four modes- \(s, x^1, y^1, d^1\). As we mentioned before they are global, i.e.
their contribution extends over the whole image. The mode \(s \) plays role similar to an averaged background.
The \(x^1\)-mode carries information about the average left-right gradient of the image. Similarly
the \(y^1\)-mode carries information about the average top-bottom gradient of the image, and
the \(d^1\)-mode carries information about the average diagonal gradient of the image. The important thing
to note here is that all of the modes are completely non-localized in both directions of the image.
Now we move to the higher modes- \(x^2, y^2, d^2\). Any of these second order modes consists of four coefficients.
For example \(x^2 \) is represented by the matrix \(x^2_{1, 1}, x^2_{1, 2}, x^2_{2, 1}, x^2_{2, 2} \).
These modes are the first to show one important property that isn't present in \(s, x^1, y^1, d^1\), namely
spacial-domain locality. In other words any modes with \( i \ge 2\) are spacialy localized, the value
of \( i \) the finer the localization. Let's assume that all the wavelet coefficients are zero with exception of \(x^2_{1, 1} \).
The image of \(x^2_{1, 1} \) in the spacial domain can be seen in the following diagram.
\(s\) | \(x^1_{1,1}\) |
\(x^2_{1,1}\) | \(x^2_{1,2}\) |
\(x^3_{1,1}\) | \(x^3_{1,2}\) |
\(x^3_{1,3}\) | \(x^3_{1,4}\) |
\(y^1_{1,1}\) | \(d^1_{1,1}\) |
\(x^2_{2,1}\) | \(x^2_{2,2}\) |
\(x^3_{2,1}\) | \(x^3_{2,2}\) |
\(x^3_{2,3}\) | \(x^3_{2,4}\) |
\(y^2_{1,1}\) | \(y^2_{1,2}\) |
\(d^2_{1,1}\) | \(d^2_{1,2}\) |
\(x^3_{3,1}\) | \(x^3_{3,2}\) |
\(x^3_{3,3}\) | \(x^3_{3,4}\) |
\(y^2_{2,1}\) | \(y^2_{2,2}\) |
\(d^2_{2,1}\) | \(d^2_{2,2}\) |
\(x^3_{4,1}\) | \(x^3_{4,2}\) |
\(x^3_{4,3}\) | \(x^3_{4,4}\) |
\(y^3_{1,1}\) | \(y^3_{1,2}\) |
\(y^3_{1,3}\) | \(y^3_{1,4}\) |
\(d^3_{1,1}\) | \(d^3_{1,2}\) |
\(d^3_{1,3}\) | \(d^3_{1,4}\) |
\(y^3_{2,1}\) | \(y^3_{2,2}\) |
\(y^3_{2,3}\) | \(y^3_{2,4}\) |
\(d^3_{2,1}\) | \(d^3_{2,2}\) |
\(d^3_{2,3}\) | \(d^3_{2,4}\) |
\(y^3_{3,1}\) | \(y^3_{3,2}\) |
\(y^3_{3,3}\) | \(y^3_{3,4}\) |
\(d^3_{3,1}\) | \(d^3_{3,2}\) |
\(d^3_{3,3}\) | \(d^3_{3,4}\) |
\(y^3_{4,1}\) | \(y^3_{4,2}\) |
\(y^3_{4,3}\) | \(y^3_{4,4}\) |
\(d^3_{4,1}\) | \(d^3_{4,2}\) |
\(d^3_{4,3}\) | \(d^3_{4,4}\) |
|
=> |
\( a_{1, 1} \) |
\( a_{1, 2} \) |
\( a_{1, 3} \) |
\( a_{1, 4} \) |
\( a_{1, 5} \) |
\( a_{1, 6} \) |
\( a_{1, 7} \) |
\( a_{1, 8} \) |
\( a_{2, 1} \) |
\( a_{2, 2} \) |
\( a_{2, 3} \) |
\( a_{2, 4} \) |
\( a_{2, 5} \) |
\( a_{2, 6} \) |
\( a_{2, 7} \) |
\( a_{2, 8} \) |
\( a_{3, 1} \) |
\( a_{3, 2} \) |
\( a_{3, 3} \) |
\( a_{3, 4} \) |
\( a_{3, 5} \) |
\( a_{3, 6} \) |
\( a_{3, 7} \) |
\( a_{3, 8} \) |
\( a_{4, 1} \) |
\( a_{4, 2} \) |
\( a_{4, 3} \) |
\( a_{4, 4} \) |
\( a_{4, 5} \) |
\( a_{4, 6} \) |
\( a_{4, 7} \) |
\( a_{4, 8} \) |
\( a_{5, 1} \) |
\( a_{5, 2} \) |
\( a_{5, 3} \) |
\( a_{5, 4} \) |
\( a_{5, 5} \) |
\( a_{5, 6} \) |
\( a_{5, 7} \) |
\( a_{5, 8} \) |
\( a_{6, 1} \) |
\( a_{6, 2} \) |
\( a_{6, 3} \) |
\( a_{6, 4} \) |
\( a_{6, 5} \) |
\( a_{6, 6} \) |
\( a_{6, 7} \) |
\( a_{6, 8} \) |
\( a_{7, 1} \) |
\( a_{7, 2} \) |
\( a_{7, 3} \) |
\( a_{7, 4} \) |
\( a_{7, 5} \) |
\( a_{7, 6} \) |
\( a_{7, 7} \) |
\( a_{7, 8} \) |
\( a_{8, 1} \) |
\( a_{8, 2} \) |
\( a_{8, 3} \) |
\( a_{8, 4} \) |
\( a_{8, 5} \) |
\( a_{8, 6} \) |
\( a_{8, 7} \) |
\( a_{8, 8} \) |
|
On the left table above we show the wavelet modes of an image of size \(2^{3}\times 2^3\). And on the right
we have the same image in spacial domain. With the red colour we denote the element in which we are interested in wavelet domain and the corresponding coefficients in spacial domain. From the
diagram we can see that the projection of the wavelet coefficient \(x^2_{1, 1} \) in spacial domain extends over the left half of the image. This means that it is localized in the horizontal direction but it is not localized in the vertical direction. The projection of the \(x^2_{2, 1} \) coincides with the one of
\(x^2_{1, 1} \). And the coefficients \(x^2_{1, 2} \) and \(x^2_{2, 2} \) contribute to the right half of the image.
Similarly the wavelet coefficient \(y^2_{1, 1} \) is localized
in the vertical but non-localized in the horizontal direction.
\(s\) | \(x^1_{1,1}\) |
\(x^2_{1,1}\) | \(x^2_{1,2}\) |
\(x^3_{1,1}\) | \(x^3_{1,2}\) |
\(x^3_{1,3}\) | \(x^3_{1,4}\) |
\(y^1_{1,1}\) | \(d^1_{1,1}\) |
\(x^2_{2,1}\) | \(x^2_{2,2}\) |
\(x^3_{2,1}\) | \(x^3_{2,2}\) |
\(x^3_{2,3}\) | \(x^3_{2,4}\) |
\(y^2_{1,1}\) | \(y^2_{1,2}\) |
\(d^2_{1,1}\) | \(d^2_{1,2}\) |
\(x^3_{3,1}\) | \(x^3_{3,2}\) |
\(x^3_{3,3}\) | \(x^3_{3,4}\) |
\(y^2_{2,1}\) | \(y^2_{2,2}\) |
\(d^2_{2,1}\) | \(d^2_{2,2}\) |
\(x^3_{4,1}\) | \(x^3_{4,2}\) |
\(x^3_{4,3}\) | \(x^3_{4,4}\) |
\(y^3_{1,1}\) | \(y^3_{1,2}\) |
\(y^3_{1,3}\) | \(y^3_{1,4}\) |
\(d^3_{1,1}\) | \(d^3_{1,2}\) |
\(d^3_{1,3}\) | \(d^3_{1,4}\) |
\(y^3_{2,1}\) | \(y^3_{2,2}\) |
\(y^3_{2,3}\) | \(y^3_{2,4}\) |
\(d^3_{2,1}\) | \(d^3_{2,2}\) |
\(d^3_{2,3}\) | \(d^3_{2,4}\) |
\(y^3_{3,1}\) | \(y^3_{3,2}\) |
\(y^3_{3,3}\) | \(y^3_{3,4}\) |
\(d^3_{3,1}\) | \(d^3_{3,2}\) |
\(d^3_{3,3}\) | \(d^3_{3,4}\) |
\(y^3_{4,1}\) | \(y^3_{4,2}\) |
\(y^3_{4,3}\) | \(y^3_{4,4}\) |
\(d^3_{4,1}\) | \(d^3_{4,2}\) |
\(d^3_{4,3}\) | \(d^3_{4,4}\) |
|
=> |
\( a_{1, 1} \) |
\( a_{1, 2} \) |
\( a_{1, 3} \) |
\( a_{1, 4} \) |
\( a_{1, 5} \) |
\( a_{1, 6} \) |
\( a_{1, 7} \) |
\( a_{1, 8} \) |
\( a_{2, 1} \) |
\( a_{2, 2} \) |
\( a_{2, 3} \) |
\( a_{2, 4} \) |
\( a_{2, 5} \) |
\( a_{2, 6} \) |
\( a_{2, 7} \) |
\( a_{2, 8} \) |
\( a_{3, 1} \) |
\( a_{3, 2} \) |
\( a_{3, 3} \) |
\( a_{3, 4} \) |
\( a_{3, 5} \) |
\( a_{3, 6} \) |
\( a_{3, 7} \) |
\( a_{3, 8} \) |
\( a_{4, 1} \) |
\( a_{4, 2} \) |
\( a_{4, 3} \) |
\( a_{4, 4} \) |
\( a_{4, 5} \) |
\( a_{4, 6} \) |
\( a_{4, 7} \) |
\( a_{4, 8} \) |
\( a_{5, 1} \) |
\( a_{5, 2} \) |
\( a_{5, 3} \) |
\( a_{5, 4} \) |
\( a_{5, 5} \) |
\( a_{5, 6} \) |
\( a_{5, 7} \) |
\( a_{5, 8} \) |
\( a_{6, 1} \) |
\( a_{6, 2} \) |
\( a_{6, 3} \) |
\( a_{6, 4} \) |
\( a_{6, 5} \) |
\( a_{6, 6} \) |
\( a_{6, 7} \) |
\( a_{6, 8} \) |
\( a_{7, 1} \) |
\( a_{7, 2} \) |
\( a_{7, 3} \) |
\( a_{7, 4} \) |
\( a_{7, 5} \) |
\( a_{7, 6} \) |
\( a_{7, 7} \) |
\( a_{7, 8} \) |
\( a_{8, 1} \) |
\( a_{8, 2} \) |
\( a_{8, 3} \) |
\( a_{8, 4} \) |
\( a_{8, 5} \) |
\( a_{8, 6} \) |
\( a_{8, 7} \) |
\( a_{8, 8} \) |
|
Finally the \( d^2 \) wavelets are localized in both horizontal and vertical direction. I.e. each of the
four coefficients \( d^2_{1, 1}, d^2_{1, 2}, d^2_{2, 1}, d^2_{2, 2} \) contributes to a block of size \(4 \times 4 \).
We illlustrate that in the next diagram.
\(s\) | \(x^1_{1,1}\) |
\(x^2_{1,1}\) | \(x^2_{1,2}\) |
\(x^3_{1,1}\) | \(x^3_{1,2}\) |
\(x^3_{1,3}\) | \(x^3_{1,4}\) |
\(y^1_{1,1}\) | \(d^1_{1,1}\) |
\(x^2_{2,1}\) | \(x^2_{2,2}\) |
\(x^3_{2,1}\) | \(x^3_{2,2}\) |
\(x^3_{2,3}\) | \(x^3_{2,4}\) |
\(y^2_{1,1}\) | \(y^2_{1,2}\) |
\(d^2_{1,1}\) | \(d^2_{1,2}\) |
\(x^3_{3,1}\) | \(x^3_{3,2}\) |
\(x^3_{3,3}\) | \(x^3_{3,4}\) |
\(y^2_{2,1}\) | \(y^2_{2,2}\) |
\(d^2_{2,1}\) | \(d^2_{2,2}\) |
\(x^3_{4,1}\) | \(x^3_{4,2}\) |
\(x^3_{4,3}\) | \(x^3_{4,4}\) |
\(y^3_{1,1}\) | \(y^3_{1,2}\) |
\(y^3_{1,3}\) | \(y^3_{1,4}\) |
\(d^3_{1,1}\) | \(d^3_{1,2}\) |
\(d^3_{1,3}\) | \(d^3_{1,4}\) |
\(y^3_{2,1}\) | \(y^3_{2,2}\) |
\(y^3_{2,3}\) | \(y^3_{2,4}\) |
\(d^3_{2,1}\) | \(d^3_{2,2}\) |
\(d^3_{2,3}\) | \(d^3_{2,4}\) |
\(y^3_{3,1}\) | \(y^3_{3,2}\) |
\(y^3_{3,3}\) | \(y^3_{3,4}\) |
\(d^3_{3,1}\) | \(d^3_{3,2}\) |
\(d^3_{3,3}\) | \(d^3_{3,4}\) |
\(y^3_{4,1}\) | \(y^3_{4,2}\) |
\(y^3_{4,3}\) | \(y^3_{4,4}\) |
\(d^3_{4,1}\) | \(d^3_{4,2}\) |
\(d^3_{4,3}\) | \(d^3_{4,4}\) |
|
=> |
\( a_{1, 1} \) |
\( a_{1, 2} \) |
\( a_{1, 3} \) |
\( a_{1, 4} \) |
\( a_{1, 5} \) |
\( a_{1, 6} \) |
\( a_{1, 7} \) |
\( a_{1, 8} \) |
\( a_{2, 1} \) |
\( a_{2, 2} \) |
\( a_{2, 3} \) |
\( a_{2, 4} \) |
\( a_{2, 5} \) |
\( a_{2, 6} \) |
\( a_{2, 7} \) |
\( a_{2, 8} \) |
\( a_{3, 1} \) |
\( a_{3, 2} \) |
\( a_{3, 3} \) |
\( a_{3, 4} \) |
\( a_{3, 5} \) |
\( a_{3, 6} \) |
\( a_{3, 7} \) |
\( a_{3, 8} \) |
\( a_{4, 1} \) |
\( a_{4, 2} \) |
\( a_{4, 3} \) |
\( a_{4, 4} \) |
\( a_{4, 5} \) |
\( a_{4, 6} \) |
\( a_{4, 7} \) |
\( a_{4, 8} \) |
\( a_{5, 1} \) |
\( a_{5, 2} \) |
\( a_{5, 3} \) |
\( a_{5, 4} \) |
\( a_{5, 5} \) |
\( a_{5, 6} \) |
\( a_{5, 7} \) |
\( a_{5, 8} \) |
\( a_{6, 1} \) |
\( a_{6, 2} \) |
\( a_{6, 3} \) |
\( a_{6, 4} \) |
\( a_{6, 5} \) |
\( a_{6, 6} \) |
\( a_{6, 7} \) |
\( a_{6, 8} \) |
\( a_{7, 1} \) |
\( a_{7, 2} \) |
\( a_{7, 3} \) |
\( a_{7, 4} \) |
\( a_{7, 5} \) |
\( a_{7, 6} \) |
\( a_{7, 7} \) |
\( a_{7, 8} \) |
\( a_{8, 1} \) |
\( a_{8, 2} \) |
\( a_{8, 3} \) |
\( a_{8, 4} \) |
\( a_{8, 5} \) |
\( a_{8, 6} \) |
\( a_{8, 7} \) |
\( a_{8, 8} \) |
|
This logic generalises for the higher order modes- the \(x^i \) get more shrinked in the horizontal direction,
the \(y^i \) get more shrinked in vertical, and the diagonal modes \(d^i \) get shrinked in both directions.
In general, if we have an image with size \(2^N \times 2^N \), the mode \(x^i \) contributes to a region of size
\(2^{N-i+1} \times 2^N \). Correspondingly \(y^i \) contributes to a region of size \(2^N \times 2^{N-i+1} \),
and \(d^i \) contributes to a region of size \(2^{N-i+1} \times 2^{N-i+1} \).
Wavelet representation of spacial domain coefficients
In the previous section we showed how the wavelet modes get peojected in spacial domain. Here we will discuss the
opposite: which wavelets cotribute to a given point \(a_{m, n} \)?
It is not hard to realise that the lowest modes: \(s, x^1, y^1, d^1 \) contribute to \(a_{m, n} \) for \( \forall m,n \) as
they have non-localized projection in spacial domain.
Next we consider the modes \(x^2_{1, 1}, x^2_{1, 2}, x^2_{2, 1}, x^2_{2, 2}\). As we stated in the previous section, the modes
\(x^2_{1, 1}, x^2_{2, 1}\) contribute to the left half of the image, and the \(x^2_{1, 2}, x^2_{2, 2}\) contribute to the right part of the image. So we choose \(x^2_{1, 1}, x^2_{2, 1}\) if \(1 \le m \le \frac{N}{2} \) and \(x^2_{1, 2}, x^2_{2, 2}\) otherwise. Similarly we need \(y^2_{1, 1}, y^2_{1, 2}\) if \(1 \le n \le \frac{N}{2} \) and \(y^2_{2, 1}, y^2_{2, 2}\) otherwise.
From the diagonal term \(d^2_{a, b}\), we choose \(a=1\) if \(1 \le m \le \frac{N}{2} \) and \(a=2\) otherwise. And
\(b=1\) if \(1 \le n \le \frac{N}{2} \) and \(b=2\) otherwise. Here it is worth nothing that although all of the different modes of second order \(x^2, y^2, d^2 \) contain 4 coefficients each, we need two coefficients from \(x^2, y^2\) and only one from \(d^2\). This is because the \(d^2\) mode is better localized in spacial domain- both in horizontal and vertical directions.
Having in mind the spacial extend of each mode, we can list all the modes that contribute to a given point or a region of an image. The needed modes are:
\begin{equation}
a_{m,n} : \{s, x^1, y^1, d^1 \} \cup \{x^i_{a_1, b_1}, y^i_{a_2, b_2}, d^i_{a_3, b_3} \}
\end{equation}
where \(i=2\ldots N\), \(a_1 = 1\ldots 2^{i-1}\), \(b_1 = m \div 2^{i-1} + 1 \), \(a_2 = n \div 2^{i-1} + 1\), \(b_2 = 1\ldots 2^{i-1}\),
\(a_3 = m \div 2^{i-1} + 1 \), \(b_3 = n \div 2^{i-1} + 1\). The sign \(\div \) denotes integer division.
As an illustration, let's suppose that we have our \(2^{3}\times 2^3\) image and we want to preserve the full information
of the point \(a_{5, 3}\) while keeping lower details (up to \(s, x^1, y^1, d^1 \) )for the rest of the image.
So we keep the lower modes (up to \(s, x^1, y^1, d^1 \) ) together with all the higher modes that contribute to \(a_{5, 3}\).
Our image in wavelet domain would look like:
\( a_{1, 1} \) |
\( a_{1, 2} \) |
\( a_{1, 3} \) |
\( a_{1, 4} \) |
\( a_{1, 5} \) |
\( a_{1, 6} \) |
\( a_{1, 7} \) |
\( a_{1, 8} \) |
\( a_{2, 1} \) |
\( a_{2, 2} \) |
\( a_{2, 3} \) |
\( a_{2, 4} \) |
\( a_{2, 5} \) |
\( a_{2, 6} \) |
\( a_{2, 7} \) |
\( a_{2, 8} \) |
\( a_{3, 1} \) |
\( a_{3, 2} \) |
\( a_{3, 3} \) |
\( a_{3, 4} \) |
\( a_{3, 5} \) |
\( a_{3, 6} \) |
\( a_{3, 7} \) |
\( a_{3, 8} \) |
\( a_{4, 1} \) |
\( a_{4, 2} \) |
\( a_{4, 3} \) |
\( a_{4, 4} \) |
\( a_{4, 5} \) |
\( a_{4, 6} \) |
\( a_{4, 7} \) |
\( a_{4, 8} \) |
\( a_{5, 1} \) |
\( a_{5, 2} \) |
\( a_{5, 3} \) |
\( a_{5, 4} \) |
\( a_{5, 5} \) |
\( a_{5, 6} \) |
\( a_{5, 7} \) |
\( a_{5, 8} \) |
\( a_{6, 1} \) |
\( a_{6, 2} \) |
\( a_{6, 3} \) |
\( a_{6, 4} \) |
\( a_{6, 5} \) |
\( a_{6, 6} \) |
\( a_{6, 7} \) |
\( a_{6, 8} \) |
\( a_{7, 1} \) |
\( a_{7, 2} \) |
\( a_{7, 3} \) |
\( a_{7, 4} \) |
\( a_{7, 5} \) |
\( a_{7, 6} \) |
\( a_{7, 7} \) |
\( a_{7, 8} \) |
\( a_{8, 1} \) |
\( a_{8, 2} \) |
\( a_{8, 3} \) |
\( a_{8, 4} \) |
\( a_{8, 5} \) |
\( a_{8, 6} \) |
\( a_{8, 7} \) |
\( a_{8, 8} \) |
|
=> |
\(s\) |
\(x^1_{1,1}\) |
\(x^2_{1,1}\) |
\(x^2_{1,2}\) |
\(x^3_{1,1}\) |
\(x^3_{1,2}\) |
\(x^3_{1,3}\) | \(x^3_{1,4}\) |
\(y^1_{1,1}\) |
\(d^1_{1,1}\) |
\(x^2_{2,1}\) |
\(x^2_{2,2}\) |
\(x^3_{2,1}\) |
\(x^3_{2,2}\) |
\(x^3_{2,3}\) | \(x^3_{2,4}\) |
\(y^2_{1,1}\) | \(y^2_{1,2}\) |
\(d^2_{1,1}\) | \(d^2_{1,2}\) |
\(x^3_{3,1}\) |
\(x^3_{3,2}\) |
\(x^3_{3,3}\) | \(x^3_{3,4}\) |
\(y^2_{2,1}\) |
\(y^2_{2,2}\) |
\(d^2_{2,1}\) |
\(d^2_{2,2}\) |
\(x^3_{4,1}\) |
\(x^3_{4,2}\) |
\(x^3_{4,3}\) | \(x^3_{4,4}\) |
\(y^3_{1,1}\) | \(y^3_{1,2}\) |
\(y^3_{1,3}\) | \(y^3_{1,4}\) |
\(d^3_{1,1}\) | \(d^3_{1,2}\) |
\(d^3_{1,3}\) | \(d^3_{1,4}\) |
\(y^3_{2,1}\) | \(y^3_{2,2}\) |
\(y^3_{2,3}\) | \(y^3_{2,4}\) |
\(d^3_{2,1}\) | \(d^3_{2,2}\) |
\(d^3_{2,3}\) | \(d^3_{2,4}\) |
\(y^3_{3,1}\) |
\(y^3_{3,2}\) |
\(y^3_{3,3}\) |
\(y^3_{3,4}\) |
\(d^3_{3,1}\) |
\(d^3_{3,2}\) |
\(d^3_{3,3}\) | \(d^3_{3,4}\) |
\(y^3_{4,1}\) | \(y^3_{4,2}\) |
\(y^3_{4,3}\) | \(y^3_{4,4}\) |
\(d^3_{4,1}\) | \(d^3_{4,2}\) |
\(d^3_{4,3}\) | \(d^3_{4,4}\) |
|
Except for the wavelet modes in colour, we can set everything else to zero. This way we have the information
for a low resolution image together with higher level details for the point \(a_{5, 3}\).
The above recipe can be easily translated into an algorithm.
The algorithm in action
We have implemented the so far discussed algorithm in our gstreamer element from the previous chapter.
The latest version is also available on
Github .
Let's start with the following pipeline
gst-launch-1.0 videotestsrc pattern=22 ! videoconvert ! video/x-raw,width=512,height=512 ! dwtfilter wavelet=h2 band=low inverse=1 cutoff=512 ! videoconvert ! autovideosink
The pipeline displays pattern 22 from the gstremear's videotestsrc element- spikes coming from the centre of the image.
We can also see the image in wavelet domain by switching the inverse property.
gst-launch-1.0 videotestsrc pattern=22 ! videoconvert ! video/x-raw,width=512,height=512 ! dwtfilter wavelet=h2 band=low inverse=0 cutoff=512 ! videoconvert ! autovideosink
So far we haven't demonstrated any new functionality apart from the one that was available before. The new functionality of the
element can be accessed via the 5 new properties.
- phof- boolean. Enable/disable a sub-region of the image where we want to preserve all the details.
- phofx- The left border of the rectangular area in which higher order modes are preserved.
- phofy- The upper border of the rectangular area in which higher order modes are preserved.
- phofw- The width of the rectangular area in which higher order modes are preserved.
- phofh- The height of the rectangular area in which higher order modes are preserved.
The above properties allow us to define a rectangular area in which we preserve all the information of the image,
while keeping the level of the detail of the rest of the image lower. In order to demonstrate that let's first reduce the
quality of the image by using our element as a low-band filter and preserve only the first \(128\times 128\) modes from the image.
gst-launch-1.0 videotestsrc pattern=22 ! videoconvert ! video/x-raw,width=512,height=512 ! dwtfilter wavelet=h2 band=low inverse=1 cutoff=128 ! videoconvert ! autovideosink
The resultant image has \(1 / 16\) of the information of the original image, and the loss of quality is noticeable. In wavelet domain it looks like
Now let's suppose that we want to preserve all the details of a square region of the image with top left corner at coordinates
\(150, 100\), width \(200\), and height \(200 \). We can achieve that with the pipeline
gst-launch-1.0 videotestsrc pattern=22 ! videoconvert ! video/x-raw,width=512,height=512 ! dwtfilter wavelet=h2 band=low inverse=1 cutoff=128 phof=1 phofx=150 phofy=100 phofw=200 phofh=200 ! videoconvert ! autovideosink
We can see that our goal is achieved- we were able to preserve the finest details of an image in a region while
keeping the resolution of the rest of the image low. Let's now look at the image wavelet domain.
gst-launch-1.0 videotestsrc pattern=22 ! videoconvert ! video/x-raw,width=512,height=512 ! dwtfilter wavelet=h2 band=low inverse=0 cutoff=128 phof=1 phofx=150 phofy=100 phofw=200 phofh=200 ! videoconvert ! autovideosink
As we can see from the picture above, there are still quite a few wavelet modes which are omitted (the black regions).
We can pack all of the non-zero modes as one continuous array and we would be able to restore the original image without
any extra information. That is because if we know the size of the image, and the coordinates of the preserved region,
we know which wavelets we need in order to reconstruct it. We just need some sort of convention, let's say the \(x\) modes are packed before \( y \) and \( d\) modes.
Limitations
The one limitation which showed-up immediately is that if we keep the level of the image very lower than the
level of the details of the region that we want to preserve, we notice some artifacts showing up.
This can be demonstrated with the pipeline
gst-launch-1.0 videotestsrc pattern=22 ! videoconvert ! video/x-raw,width=512,height=512 ! dwtfilter wavelet=h2 band=low inverse=1 cutoff=16 phof=1 phofx=150 phofy=100 phofw=200 phofh=200 ! videoconvert ! autovideosink
And in wavelet domain:
Conclusion
The demonstrated element has the capability to reduce the overall quality of an image while preserving all details in some
particular region of it. This could be achieved thanks to the localization properties of the wavelets- the higher the wavelet number, the better it is localized in the spacial domain, either in horizontal, vertical, or both directions.