Quadtrees are an effective method to store and locate data of points in a two-dimensional plane. Another effective use of quadtrees is in the field of image manipulation.
Unlike in storage of points, in image manipulation we get a complete quadtree with the leaf nodes consisting of individual pixels of the image. Due to this, we can utilize an array to store the nodes of the tree. This leads to less memory needed (compared to linked representation) for processing.
The lowest level of the quadtree would contain N nodes equivalent to the number of pixels in the image. The next level would contain N / 4 nodes.
Thus, the total number of nodes necessary can be found by: N + N / 4 + N / 16 + … + 1.
To get an upperbound we can use sum of geometric progression to infinity
Nodes = N / (1 – 1 / 4) = 4 / 3 * N
This is the size of the array necessary.
Thus, the amount of memory needed is O(N)
The above code in Python shown demonstrates the class definition of a pixel.
Unlike in a classic quadtree, for image manipulation, we can insert all the nodes in O(N) time complexity.
First, we insert all the leaf nodes directly into the last N positions of the array. The following code snippet demonstrates this:
In the above snippet, self.tree is the array of nodes, self.size is the total size of the array, and self.image is the pixels of the image, count is used to traverse the tree.
For nodes that aren’t leaves, the R, G, B values are calculated by taking the average of the values of the children.
The topLeft and bottomRight are obtained by taking the maximum and minimum values of the x and y of the children.
Here we can see, we take the values of R, G, B of the four children, and we divide by 4, thus getting the average.
Calculation of these values happen in O(1) time assuming values of the children are known. Since we are moving in reverse order, the values of the children are computed before that of parents.
Thus insertion occurs in O(N).
Application in Image Manipulation
Let us say we wish to convert a high quality image to a thumbnail. Once we have created a quadtree for the image, by selecting a height of the quadtree we can select the quality of the image we obtain. If the height is equal to the height of the quadtree, then we retain the original image. At lower heights, we obtain images of lesser quality.
In case we do not wish to reduce the quality of the image, we can try to compress the image by what is known as “pruning”. In this, leafs with colours close to that of their parents are removed. This is continuously done until no further leaves can be removed. The lowest level is then taken to form the image, using only leaf nodes. While this does not reduce the quality of the image drastically, it can lead to a small compression of the image.
This article is contributed by Aditya Kamath. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to firstname.lastname@example.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
- Image Processing in Java | Set 4 (Colored image to Negative image conversion)
- Image Processing in Java | Set 6 (Colored image to Sepia image conversion)
- Image Processing in Java | Set 3 (Colored image to greyscale image conversion)
- Image Processing in Java | Set 5 (Colored to Red Green Blue Image Conversion)
- MATLAB | Converting a Grayscale Image to Binary Image using Thresholding
- Image Processing in Java | Set 7 (Creating a random pixel image)
- Image Processing in Java | Set 11 (Changing orientation of image)
- Getting started with Scikit-image: image processing in Python
- Image Processing in Java | Set 8 (Creating mirror image)
- MATLAB | RGB image to grayscale image conversion
- Image Processing in Java | Set 10 ( Watermarking an image )
- Image Formats
- What is Image Blurring
- Matlab | Erosion of an Image
- Python PIL | Image.new() method