This post is an extension of this content

**All the codes can be accessed by clicking the titles of each exercise.
** The root directory can be accessed here.

## 7.2: Homomorphic filter

The purpose of this exercise is to implement a homomorphic filter. The next figure illustrates the desired effect

This type of filtering is based on the frequency domain, with the Fourier transform from the space domain.The concept of the homomorphic filter comes from the illumination and reflectance of an image, the illumination has slow variations of tones or lower frequencies, while the reflectance has faster variations of tones or higher frequencies. The intention of the filter is to attenuate the lower frequencies, turning the reflectance of the image stronger, giving the effect of a fine tuned contrast. The high-pass filter can be approximated by the following Gaussian filter

The next lines of code illustrates the gaussian filter being prepared, based on the previous image

for(int i=0; i<dft_M; i++){ for(int j=0; j<dft_N; j++){ d2 = (i-dft_M/2)*(i-dft_M/2)+(j-dft_N/2)*(j-dft_N/2); filter.at(i,j) = (yh-yl)*(1.0-(float)exp(-(c*d2/(d*d))))+yl; } }

Then, the image is filtered in the frequency domain with the “mulSpectrums” function (after some adaptations in the original figure) from the OpenCV library:

mulSpectrums(complexImage,filter,complexImage,0);

## 8.3: Pointillism

This artistic exercise aims to apply the gorgeous pointillism effect on a given image, with a fine grain tuning based on the borders of the image.

The next image is going to be the example of this exercise (as default haha).

The well-known “Canny” algorithm is used to detect the borders. For a given threshold, the result is:

On my implementation, I have filled the image with circles, based on the original image as:

The circles are filled based on the color of the pixels of the image, and a random selection of those pixels and where they should be drawn. In the next snippet of code the circles are drawn on the image, the “JITTER” variable will choose the color of the pixel on a given position with a random offset, the “RAIO” variable controls the size of the circle. The “STEP” variable is used to fill only certain positions of the image with circles, so it returns a better visual result.

#define STEP 3 #define JITTER 2 #define RAIO 3 for(auto i : xrange){ random_shuffle(yrange.begin(), yrange.end()); for(auto j : yrange){ x = i+rand()%(2*JITTER)-JITTER+1; y = j+rand()%(2*JITTER)-JITTER+1; gray = image.at(x,y); circle(points, cv::Point(y,x), RAIO, CV_RGB(gray,gray,gray), -1, CV_AA); } }

Then, based on the borders detected by the Canny algorithm, the code draws circles with smaller radius, lower jitter and closer to each other, choosing the right spots with the if:

//"border" stores the borders information if(border.at(i,j)!=0){

The code will only drawn circles, if a border is detected at the same pixel. The result is:

## 9.2: K-means with random centers

In this exercise, the randomization of the initial centers for the k-means algorithm will be analysed.

The k-means is a quantization algorithm, it attempts to represent all the different colors in an image into a sub-group of colors. Those new groups or classes are fixed by a center, which is adapted iteratively during the algorithm execution. The result is directly related on how the initial centers are defined. Let’s consider the next reference image:

By using the built-in OpenCV kmeans function, it is possible to choose the location method for the initial centers. Considering the “KMEANS_PP_CENTERS” probabilistic method by Arthur and Vassilvitskii

as:

kmeans(samples, nClusters, rotulos, TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10000, 0.0001), nRodadas, KMEANS_PP_CENTERS, centros );

The result is:

It is important to notice that the k-means method is not deterministic, which may deliver different results with different executions.

Then, the centers initialization is changed with the “KMEANS_RANDOM_CENTERS” flag, returning:

It is possible to notice that the random center oscillates the results slightly more, this is due to the stronger stochastic behavior of the random method compared to the Arthur’s one. The k-means algorithm is deterministic after choosing the initial centers.