How to implement rendering transformations on Geoserver using NDVI index? - geoserver

I want to implement a rendering transformation using the NDVI index on grayscale tiff. I am following this link:-
https://docs.geoserver.org/stable/en/user/styling/sld/extensions/rendering-transform.html
What type of data will work for it?
I tried the sld provided in the Geoserver manual, but that doesn't seem to work on my data, but on applying that style, it does not work
<NamedLayer>
<Name>cite:NDVI</Name>
<UserStyle>
<Title>NDVI</Title>
<FeatureTypeStyle>
<Transformation>
<ogc:Function name="ras:Jiffle">
<ogc:Function name="parameter">
<ogc:Literal>GRAY_INDEX</ogc:Literal>
</ogc:Function>
</ogc:Function>
</Transformation>
<Rule>
<RasterSymbolizer>
<Opacity>1.0</Opacity>
<ColorMap>
<ColorMapEntry color="#0000ff" quantity="-0.17"/>
<ColorMapEntry color="#548022" quantity="0.07"/>
<ColorMapEntry color="#f6f7f5" quantity="0.4"/>
</ColorMap>
</RasterSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
I want my grayscale tiff to be transformed to NDVI band color mapping.

The page you link to shows how to calculate NDVI from a multiband Sentinel image by combining bands 3 and 7, using this formula.
nir = src[7];
vir = src[3];
dest = (nir - vir) / (nir + vir);
Your grayscale image only has one band so it is impossible to calculate NDVI from it.

Related

How to make the Geoserver SLD with vector layer(linestring geometry) if rasterize gray color lines to RGB color line using RasterSymbolizer Colormap?

I am a starter with the Geoserver.
I created lineString vector layer with lineSymbolizer SLD style.
And the vector layer is connected by postgis and that layer only have linestring geometry rowdata. other attributes values does not exist(only linstring coordinates)
grayscaled layer
<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.0.0"
xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
xmlns="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- a Named Layer is the basic building block of an SLD document -->
<NamedLayer>
<Name>line</Name>
<UserStyle>
<Title>Line</Title>
<Abstract>greyscaled line</Abstract>
<FeatureTypeStyle>
<Rule>
<Name>rule1</Name>
<Title>greyscaled Line</Title>
<Abstract></Abstract>
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#000</CssParameter>
<CssParameter name="opacity">0.1</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
and I want to convert or set this layer greyscaled color to RGB coloring by quantity.
the outputs should be like this image
RGB Colormap
Geoserver RasterSymbolizer
I tried make new SLD using 'RasterSymbolizer Colormap' from geoserver, but I failed..
Is it possible use rasterSymbolizer in linestring vector layer map?

Polygon on Raster query in GeoServer

I need to perform a polygon on raster cookie-cut and pixel sum using GeoServer. The polygon (GeoJSON) and raster are both in WGS84 (4326). The raster is a very large GeoTIFF population raster published with GeoServer. I have two questions:
How to do the entire operation in GeoServer?
Alternatively, how to query the raw pixel values from the rectangular extent of the polygon (minx, miny, maxx, maxy), and I can do the pixel in/out sum analysis myself.
I have tried WMS queries and WCS queries but cannot find a way to request the raw pixel values rather than a PNG rendered result. I have also tried some WPS sample queries, with no success. I'm not seeing much from Google on polygon-on-raster statistics. Is this entire query possible in GeoServer? Or is at least fetching a rectangular area of raw pixels from the GeoTIFF from GeoServer possible?
Thanks!!
To fetch a rectangle of pixels as a GeoTiff you would need to use a WCS request. The easiest way to define one of those is using the WCS Request generator - for example:
<?xml version="1.0" encoding="UTF-8"?><GetCoverage version="1.0.0" service="WCS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wcs" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xsi:schemaLocation="http://www.opengis.net/wcs http://schemas.opengis.net/wcs/1.0.0/getCoverage.xsd">
<sourceCoverage>nurc:Pk50095</sourceCoverage>
<domainSubset>
<spatialSubset>
<gml:Envelope srsName="EPSG:32633">
<gml:pos>347649.93086859107 5176214.082539256</gml:pos>
<gml:pos>370725.976428591 5196961.352859256</gml:pos>
</gml:Envelope>
<gml:Grid dimension="2">
<gml:limits>
<gml:GridEnvelope>
<gml:low>0 0</gml:low>
<gml:high>545 490</gml:high>
</gml:GridEnvelope>
</gml:limits>
<gml:axisName>E</gml:axisName>
<gml:axisName>N</gml:axisName>
</gml:Grid>
</spatialSubset>
</domainSubset>
<output>
<crs>EPSG:32633</crs>
<format>GeoTIFF</format>
</output>
</GetCoverage>
To extract values of a raster bounded by a polygon you can use a WPS request to crop to a polygon and then sum the pixels yourself:
<?xml version="1.0" encoding="UTF-8"?><wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wcs="http://www.opengis.net/wcs/1.1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">
<ows:Identifier>ras:CropCoverage</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>coverage</ows:Identifier>
<wps:Reference mimeType="image/tiff" xlink:href="http://geoserver/wcs" method="POST">
<wps:Body>
<wcs:GetCoverage service="WCS" version="1.1.1">
<ows:Identifier>nurc:Pk50095</ows:Identifier>
<wcs:DomainSubset>
<ows:BoundingBox crs="http://www.opengis.net/gml/srs/epsg.xml#32633">
<ows:LowerCorner>347649.93086859107 5176214.082539256</ows:LowerCorner>
<ows:UpperCorner>370725.976428591 5196961.352859256</ows:UpperCorner>
</ows:BoundingBox>
</wcs:DomainSubset>
<wcs:Output format="image/tiff"/>
</wcs:GetCoverage>
</wps:Body>
</wps:Reference>
</wps:Input>
<wps:Input>
<ows:Identifier>cropShape</ows:Identifier>
<wps:Data>
<wps:ComplexData mimeType="application/wkt"><![CDATA[POLYGON((x1 y1, x2 y2,......))]]></wps:ComplexData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput mimeType="image/tiff">
<ows:Identifier>result</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>
Or you could write your own custom process to carry out the whole process in one go.

Writing a greyscale video using Videowriter/avifile

I am writing a function that generates a movie mimicking a particle in a fluid. The movie is coloured and I would like to generate a grayscaled movie for the start. Right now I am using avifile instead of videowriter. Any help on changing this code to get grayscale movie? Thanks in advance.
close all;
clear variables;
colormap('gray');
vidObj=avifile('movie.avi');
for i=1:N
[nx,ny]=coordinates(Lx,Ly,Nx,Ny,[x(i),-y(i)]);
[xf,yf]=ndgrid(nx,ny);
zf=zeros(size(xf))+z(i);
% generate a frame here
[E,H]=nfmie(an,bn,xf,yf,zf,rad,ns,nm,lambda,tf_flag,cc_flag);
Ecc=sqrt(real(E(:,:,1)).^2+real(E(:,:,2)).^2+real(E(:,:,3)).^2+imag(E(:,:,1)).^2+imag(E(:,:,2)).^2+imag(E(:,:,3)).^2);
clf
imagesc(nx/rad,ny/rad,Ecc);
writetif(Ecc,i);
if i==1
cl=caxis;
else
caxis(cl)
end
axis image;
axis off;
frame=getframe(gca);
cdata_size = size(frame.cdata);
data = uint8(zeros(ceil(cdata_size(1)/4)*4,ceil(cdata_size(2)/4)*4,3));
data(1:cdata_size(1),1:cdata_size(2),1:cdata_size(3)) = [frame.cdata];
frame.cdata = data;
vidObj = addframe(vidObj,frame);
end
vidObj = close(vidObj);
For your frame data, use rgb2gray to convert a colour frame into its grayscale counterpart. As such, change this line:
data(1:cdata_size(1),1:cdata_size(2),1:cdata_size(3)) = [frame.cdata];
To these two lines:
frameGray = rgb2gray(frame.cdata);
data(1:cdata_size(1),1:cdata_size(2),1:cdata_size(3)) = ...
cat(3,frameGray,frameGray,frameGray);
The first line of the new code will convert your colour frame into a single channel grayscale image. In colour, grayscale images have all of the same values for all of the channels, which is why for the second line, cat(3,frameGray,frameGray,frameGray); is being called. This stacks three copies of the grayscale image on top of each other as a 3D matrix and you can then write this frame to your file.
You need to do this stacking because when writing a frame to file using VideoWriter, the frame must be colour (a.k.a. a 3D matrix). As such, the only workaround you have if you want to write a grayscale frame to the file is to replicate the grayscale image into each of the red, green and blue channels to create its colour equivalent.
BTW, cdata_size(3) will always be 3, as getframe's cdata structure always returns a 3D matrix.
Good luck!

segment object(leaf) which is on the white paper using image processing

I want to get only leaf from an image.
The background is a normal white paper(A4) and there is some shadow.
I apply some method (structure element,edge detection using filter) but I cannot find the general way which can apply all the image.
these are examples.
Are there better methods for this problem??
thank you
another example.
and the result I got is
By using
hsv_I = rgb2hsv(I);
Is = hsv_I(:,:,2);
Is_d = imdilate(Is,strel('diamond',4));
Is_e = imerode(Is,strel('diamond',2));
Is_de = imerode(Is_d,strel('disk',2));
Is_def = imfill(Is_de,'holes');
Is_defe = imerode(Is_def,strel('disk',5));
Then Is_defe is a mask to segment
But the method that i did is very specific. I cannot use this in general.
If you have the Image Processing Toolbox, you could do as follows:
The code below first estimates the threshold with the function graythresh, thresholds the image and fills holes with the imfill function. Suppose I is a cell containing your RGB images:
for k=1:length(I)
t=graythresh(rgb2gray(I{k}));
BW{k}=imfill(~im2bw(I{k}, t), 'holes');
subplot(length(I),1,k), imshow(BW{k});
end

Mapping image into cylinder or sphere shape?

So lets say I have black & white image that is read with imread() command and saved into matrix A.
I want to output/graph this matrix A image in a cylinder shape. I know how to draw a cylinder in MATLAB, but I do not have a clue what I should do if I want to put image on a cylinder or draw image in cylinder shape. Any help will be appreciated. Thank you.
I found this site from googling.
http://www.flashandmath.com/advanced/rolls/cylin.html
This is exactly what I want to do, but I need to do this in MATLAB.
The technique is called texture mapping. This is a code example from surface function (R2011b):
load clown
surface(peaks,flipud(X),...
'FaceColor','texturemap',...
'EdgeColor','none',...
'CDataMapping','direct')
colormap(map)
view(-35,45)
This example loads RGB image from "peppers.png" and maps it onto cylinder:
imgRGB = imread('peppers.png');
[imgInd,map] = rgb2ind(imgRGB,256);
[imgIndRows,imgIndCols] = size(imgInd);
[X,Y,Z] = cylinder(imgIndRows,imgIndCols);
surface(X,Y,Z,flipud(imgInd),...
'FaceColor','texturemap',...
'EdgeColor','none',...
'CDataMapping','direct')
colormap(map)
view(-35,45)
Things are even simpler with the warp function (comes with Image Processing toolbox) as natan suggested:
imgRGB = imread('peppers.png');
[imgRows,imgCols,imgPlanes] = size(imgRGB);
[X,Y,Z] = cylinder(imgRows,imgCols);
warp(X,Y,Z,imgRGB);

Resources