Linear regression between every 3×3 pixels of two rasters

6 views (last 30 days)
I have two rasters of land surface temperature and elevation, LST and ELEV. They have equal number of rows and columns (same boundary, same number of pixels).I want to create a new raster of regression slope or temperature lapse rate (RSLOPE) with same number of rows and columns as LST and ELEV. I want to create this raster by performing linear regression between every 3×3 pixels of the two rasters (LST and ELEV) such that each pixel of the RSLOPE will hold the regression slope value obtained from linear regression of the corresponding 3×3 pixels in LST and elev that surround that pixel.

Accepted Answer

Guillaume
Guillaume on 12 Apr 2018
For what you want to do, blockproc wouldn't work as it does not overlap the blocks. nlfilter and colfilt do on the hand, but none of these functions take two images as inputs. In addition nlfilter and colfilt both do zero-padding at the end which is not what you want.
What I don't understand is why you only expect one image out of your linear regression. You usually get two terms out of a linear regression, the slope and the offset. The equation of the line in your image is incorrect, it's actually LST = RSLOPE * ELEV + ROFFSET.
Regardless, what you could use is im2col to convert the blocks of both input images into columns, perform your regression on each column, then reshape the result back to an image.
collst = im2col(LST, [3 3]);
colelev = im2col(ELEV, [3 3]);
rslope = zeros(1, size(collst, 2));
roffset = rslope;
%perform linear regression on each column
for col = 1:size(collst, 2)
p = polyfit(colelev(:, col), collst(:, col), 1);
rslope(col) = p(1);
roffset(col) = p(2);
end
%reshape result
rslope = reshape(rslope, size(LST, 1) - 2, size(LST, 2) - 2);
roffset = reshape(roffset, size(LST, 1) - 2, size(LST, 2) - 2);
The slowest part of the above is going to be the polyfit applied to each column one by one. As it's a linear regression, the equations for the slope and offset are well know so you could implement them directly instead of using polyfit. The advantage of that would be much faster processing as you could apply the equation directly to the whole collst and colelev matrices without a loop.
You'll note that the result is 2 rows and columns shorter than the inputs. While im2col doesn't do padding, it also does not do shrinking of the blocs, so the edges are ignored. I don't have a solution for that.
  6 Comments
Guillaume
Guillaume on 28 Apr 2018
"This thread will be very useful to someone ..."
Then I suggest you accept the answer.
"Can we write the 'slope' matrix created at the end into a raster"
The easiest is to rescale it to (1, 255) and save it as indexed
rasterslope = 1 + (slope - min(slope(:)) / (max(slope(:)) - min(slope(:)) * 255;
imwrite(rasterslope, parula(256), 'somename.png');
Alejandro
Alejandro on 28 Apr 2018
I am sorry I did not realise that I have not already accepted the answer. I converted the matrix into ASCII file and then converted ASCII to raster using ArcGIS and then later georeferenced it. Many thanks again for your kind support and serious consideration.This was really helpful and needed.

Sign in to comment.

More Answers (0)

Categories

Find more on Line Plots in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!