swarm-lab / Rvision

Basic computer vision library for R
https://swarm-lab.github.io/Rvision/
GNU General Public License v3.0
141 stars 34 forks source link

Downsample an image using Gaussian filter #66

Closed nikosGeography closed 1 year ago

nikosGeography commented 1 year ago

Correct me if I am wrong, but the function gaussianBlur returns a blurred image with the same pixel size as the input. It would be nice to develop an algorithm that downsamples an image (i.e., makes the pixel size bigger) using the gaussianBlur.

So, in theory, for each coarse pixel all is needed is to go to its center and calculate the weights (Gaussian filter) needed for each fine pixel surround it. To do this we need to apply a Gaussian filter to the fine data, but with a very large width. The units of the Gaussian should be in pixels (as well as the units of the StD).

As far as I am concerned, there is no other package in R that performs this kind of downsampling.

sjmgarnier commented 1 year ago

@nikosGeography Are you talking about Gaussian pyramids?

nikosGeography commented 1 year ago

@sjmgarnier in theory I am talking about the point spread function (PSF) and how it affects the images. Gaussian pyramids are reducing the pixel size by an integer factor, as far as I know.

sjmgarnier commented 1 year ago

@nikosGeography I guess I don't understand what you mean by pixel size in this case. A Gaussian pyramid is simply applying a Gaussian filter to an image and then removing all even rows and columns of the image (effectively downsampling it by a factor of 2 at each cycle of the pyramid).

Are you suggesting instead that the intensity at any arbitrary point with continuous coordinates is the sum of the intensities of the surrounding pixels with weights determined by a Gaussian-shaped function of their distance to that arbitrary point?

sjmgarnier commented 1 year ago

@nikosGeography Maybe a more straightforward way would be for you to point me toward the desired algorithm in a different language. I can then see how easily I can implement it in Rvision.

nikosGeography commented 1 year ago

Sure. This is something similar to what I am suggesting. It is written in Matlab.

If you want the exact method then you should have a look at this code. In this code they perform several (irrelevant to what I am suggesting) methods, like regression and kriging interpolation, but the first step they do is to downsample an image using a Gaussian filter kernel.

So far I haven't found anything else in Python or in R. I could suggest a paper as well where they discuss in depth the concept of downsampling a satellite image using a Gaussian filter.

I would be more than happy to discuss in more detail my suggestion because it's something that hasn't been done on R.

sjmgarnier commented 1 year ago

@nikosGeography The first code looks very much like a Gaussian pyramid, no? Blur followed by removal of even rows and columns. Or am I completely missing something? (it's late, I probably am)

nikosGeography commented 1 year ago

@sjmgarnier it's really late, that's for sure so maybe I am not explaining my suggestion in the best possible way. Would it be possible to send you an e-mail tomorrow morning, explaining in detail what I want to achieve? Of course, I will update this post as well.

sjmgarnier commented 1 year ago

@nikosGeography Sure. Just to make sure, this (below) is NOT what you're looking for, right?

library(Rvision)

zoom <- 2
sigma <- 0.8 * sqrt(zoom * zoom - 1)

balloon <- image(system.file("sample_img/balloon1.png", package = "Rvision"))
balloon_blurred <- gaussianBlur(balloon, 21, 21, sigma, sigma)
balloon_zoomed <- resize(balloon_blurred, fx = 1 / zoom, fy = 1 / zoom)

plot(balloon_zoomed)
nikosGeography commented 1 year ago

Unfortunately I can't test it because of the R version I am using right now. Suppose I have an image with a spatial resolution (i.e., pixel size) of 100m and I want to aggregate that image to 460m spatial resolution. This means that to make each pixel, in the output image, 460m (the dimensions of each pixel).

This aggregation (or downsampling) should be done using a Gaussian filter. The filter should be expressed in pixels. Let's say I set the sigma to 0.5 pixels. So, in your example:

zoom = 4.6
sigma = 0.5

What should be the width of the Gaussian filter in order for the pixels to become 460m?

I apologize for using such an example with such big pixel size but my background is from satellite remote sensing.

I can share my data if you want to or we could wait until tomorrow morning so I can install a more recent version of R in my laptop and test the algorithm.

sjmgarnier commented 1 year ago

@nikosGeography Send me an email tomorrow. In the Matlab code that you sent me (if I understand it correctly), the Gaussian filtering and the downsampling are two separate steps. The only thing that they have in common is that sigma depends on the zoom factor. In other words, the Gaussian filter does not downsample the image. It is a preparatory step to eliminate high-frequency information in the original image that could cause artifacts during the downsampling operation.

nikosGeography commented 1 year ago

Probably you are right. I am not familiar with Matlabcode but one thing I do know is that the downsampling and the Gaussian filter should be the same step. On the other hand, the second code that I sent you (the one with the regression etc) for sure is the right one because it's the one I am trying to replicate (although way more complex to copy it).

Thank you so far for you help.

sjmgarnier commented 1 year ago

@nikosGeography As far as I can tell, the second code only creates a kernel of some sort. It's very short and doesn't contain the other irrelevant steps that you mention. Are you sure that you posted the right link?

nikosGeography commented 1 year ago

Yes I am sure. the code I posted contained only part of the process. Here is the whole process (downsampling, regression, kriging etc). This might be a bit too complicated, but I know which .m files are irrelevant (or I know most of them).

nikosGeography commented 1 year ago

@sjmgarnier would it be possible to send me your e-mail because I can't find it? Many thanks.

sjmgarnier commented 1 year ago

@nikosGeography It's garnier@njit.edu.