The white line in the bottom image is the cross section that we are looking at in the top half.
This first image shows the pebbles with very small gradients.
This second image shows the pebbles with very small larger gradients, and clipping at the highest pebble.
Using different colour splines
A simple image with its segmentation. The borders are wrapping around, as can be seen by the same colour segments on the left and right sides of the image
Some more complicated images with their segmentation
Some results from this input image
Here is what the segmented regions look like
So far, only the diffuse lighting is rendered on the pebbles. Here are some different results, each with slightly different settings. The input image is 400px by 400px. The x and y positions of the light are in the middle of the image, and the light is getting further away from the image in each picture. There are 200 segments in this image. Processing time was around 10 mins.
Dist between pixels; 1 unit
Light’s height; 1000 units
Dist between pixels; 5 unit
Light’s height; 5000 units
Dist between pixels; 10 unit
Light’s height; 10000 units
Dist between pixels; 15 unit
Light’s height; 15000 units
Dist between pixels; 20 unit
Light’s height; 20000 units
As you can see, there is a lot of clipping in the final images, and the boundaries of the regions do not have a proper gradient.
This final image was an early render of the diffuse lighting. It has many artifacting issues, and since the shapes are larger and longer, it has odd gradients that make it look like a height map of mountains rather than pebbles.
Here is a picture of the pebbles created, along with the original image, the eroded image and a sample field of one of the regions. At the moment, not all regions will work, there are problems when a region is too small or is eroded to nothing.
Using a point as the interior contour is problematic for some irregularly shaped segments. Since the point is simply the average of all of the points that make up the boundary, the output will be biased towards it. This can be seen in the output of the previous post.
This can be solved by using an offset of the boundary, as can be seen here with the blue and red lines. Ehren has a function to take care of this, however it cannot offset it very far.
A solution to this is to use morphological erosion. The technique includes going around the boundary pixel by pixel and removing any parts of the region that are within a certain distance of this boundary pixel. The outcome will look like this;
With this technique, we are able to erode to any size we want, by just changing a single number. The above example is a 4px erosion, whereas the bottom example is a 20px erosion.
While looking back at some of my base code, as well as the classes I’ve created for this project, I found an abundance of C++ malpractices that I was not aware of at the time of writing. The list includes;
-Implementing functions in the header file
-Initializing variables in the header file
-Multiple classes in a single .cpp file
-Overwrote Ehren’s main function and added my own functions to his code instead of calling his functions
-Had no function prototypes in the header file, all inside the .cpp
-Included a .cpp file from a header
-Not using OOP when it was a much better option
This lead to me re-witing a lot of my code base, as well as upgrading to a new version of Ehren’s library. This fixed all of the OpenCV and Boost related problems I was having, and allowed me to use a point as the interior contour rather than a polygon. Here are some results.
Input;
Example of the combined contours;
Output;
As you can see in the output, the regions are not representing the full shapes that they should be. Another problem is when the regions overlap, they have no way of taking an average between what the edges should be.
This is a sample image that I have been using for extracting the regions by colour.
After I extract each region, I can use the boundary as a polygon, and find the normalized representation. Here are the results from all 4 regions.
I have almost finished implementing the boundary detection code in C++. Pictures coming soon.