GDAL hillshade artifacts - gdal

I'm using gdal to create different kinds of layers, such as color reliefs and hillshades, and Mapnik to combine them into a single image to use as texture for the 3D dem model obtained from a single .hgt file.
Premising that I'm new to gdal, I'm facing some problem with the hillshade layer.By using the gdal command:gdal_translate N44E007.hgt N44E007.tif
I get the N44E007.tif file, which in IrfanView looks like this
With the following gdal command:gdaldem hillshade -of PNG .\tif\N44E007.tif .\hillshade_png\N44E007_hillshade.png
The N44E007_hillshade.png file I get is the following
How can I prevent gdal from creating these artifacts in the hillshade .png?
I'm using Windows 7 and cmd.
Update 1
This is the image I get by replacing gdal_translate N44E007.hgt N44E007.tif with gdalwarp -t_srs EPSG:32632 -r bilinear N44E006.hgt N44E006.tif
The problem is that the reprojected image is slightly rotated and stretched. How can I get a squared and straight image to use as texture for a 3d plane?

The reason for the artefacts in the first attempt is because the raster horizontal distance units are in degrees, and the vertical are in meters. You can use a scale option to normalise horizontal and vertical distance units, e.g. try:
gdaldem hillshade -s 111120 -compute_edges -of PNG N44E007.hgt N44E007_hs.png
The second attempt (Update 1) reprojects to WGS84 UTM zone 32, which is a transverse Mercator projection centred on a meridian at 9°E, which is close to the SRTM raster, which is centred on 7.5°E. Since the two meridians are not the same, it is expected the raster to be rotated. And it is stretched since the true distance of degrees are not equal in N-S and E-W directions, except at the equator.

Related

How to correctly use ogr2ogr and gdal_rasterize to rasterize a smaller area of a large vector of GeoPackage?

I am using gdal_rasterize and ogr2ogr with a goal to get a partial raster of .gpkg file.
With first command I want to clip a smaller area of a large map.
ogr2ogr -spat xmin ymin xmax ymax out.gpkg in.gpkg
This results in a file that with command ogrinfo out.gpkg gives expected output by listing the layers numbers and names.
Then trying to rasterize this new file with:
gdal_rasterize out.gpkg -burn 255 -ot Byte -ts 250 250 -l anylayer out.tif
results in: ERROR 1: Cannot get layer extent when tried with any of the layers names given by ogrinfo
Using the same command on the original in.gpkg doesnt give errors and results in expected .tiff file raster.
ogr2ogr --version GDAL 2.4.2, released 2019/06/28
gdal_rasterize --version GDAL 2.4.2, released 2019/06/28
This process should at the end be implemented with the gdal C++ API.
Are the commands given some how invalid this way, how?
Should the whole process be done differently, how?
What does the ERROR 1: Cannot get layer extent mean?

Transforming Robinson to EPSG:3857 with GDAL

I’m trying to convert a full globe Robinson Projection to Mercator. For example, I use this image.
First, I apply geo-tagging:
gdal_translate -a_ullr -180 90 180 -90 -a_srs ESRI:54030 source.jpg source_tagged.tif
and finally warp it to Mercator:
gdalwarp -t_srs ESRI:54030 -s_srs EPSG:3857 source_tagged.tif target.tif
The outcome is slightly stretched vertically but nowhere near proper Mercator. What am I doing wrong?
There are a couple of issues in your commands. The first is that -180 90 isn't in the top left corner pixel of global Robinson projection GeoTIFFs. The top left corner would be something like -338.2187147689 90, and the bottom right would be 338.2187147689 -90. However, you're also specifying your srs as ESRI:54030, so those bounds need to be in projected coordinates, not lat/lons. The command to generate a GeoTIFF from your image would be:
gdal_translate -a_ullr -17005833.3305252 8625154.47184994 17005833.3305252 -8625154.47184994 -a_srs ESRI:54030 source.jpg source_tagged.tif
Your second command has the -t_srs and -s_srs switched. Given that you're projecting to EPSG:3857, you'll also need to provide bounds since Mercator goes to infinity at the poles. So the updated command will look like:
gdalwarp -s_srs ESRI:54030 -t_srs EPSG:3857 -te -180 -81 180 81 -te_srs EPSG:4326 source_tagged.tif target.tif
I made the following projected image from your example using these commands (cropping the whitespace in the image prior to running them).

How to get DPI of a PDF file?

Using ImageMagick or GhostScript or any PHP code how can I get the DPI value of PDF files?
Here is the link for two demo files
http://jmp.sh/O5g5wL4 -- of 72 DPI
http://jmp.sh/RxrnYrY -- of 300 DPI
I have used
$image = new Imagick();
$image->readImage('xyz.pdf');
$resolutions = $image->getImageResolution();
It gives the same result for two different PDF files having different DPI.
I have also used
pdfimages -list xyz.pdf
It gives a list of all information but how to fetch the DPI value from the list.
How to get the exact DPI value of a PDF?
As fmw42 says PDF files themselves have no resolution. However in your case both the files consist of nothing but an image. In one case the image is ~48 MB and in the other its around 200 MB.
The reason is that the images have a different effective resolution.
In PDF the image is simply a bitmap, a sequence of coloured pixels. These are then drawn onto the underlying media. At this point there is no resolution, the pixels are laid down in a specific media size. In your case 22 inches by 82 inches.
The effective resolution is given by dividing the dimension by the number of pixels in the image in that dimension.
So if I have an image which is 1000x1000 pixels, and I draw it in a 1 inch square, then the effective resolution of the image is 1000 dpi. If I change my mind and draw it in a square 4 inches by 4 inches, then the effective resolution is 250 dpi.
The image hasn't changed, just the area it covers.
Now consider I have two images drawn in 1 inch squares. the first image is 1000x1000, the second is 500x500. The effective resolution of the first image is 1000 dpi, the effective resolution of the second is 500 dpi.
So you can see that, in PDF, the effective resolution of the image is a combination of the dimensions of the image, and the dimensions of the media it covers.
That's a difficult thing to measure in a PDF file. The area covered is calculated using matrix algebra and can be a combination of several different matrices.
The actual dimensions of the image, by contrast are quite easy to determine, they are given in the image dictionary. Your images are: 1620x5868 and 3372x12225. In both cases the media is the same size; 22.5x81.5 inches.
Since the images cover the entire media, the effective resolutions are;
1620/22.5 = 72 by 5868/81.5 = 72
3372/22.5 = 149.866 by 12225/81.5 = 150
I think MuPDF will give you image dimensions and media dimensions, assuming all your PDF files are constructed like this you can then simply perform the maths, but note that this won't be so simple for ordinary PDF files where images don't cover the entire media.
Using mutool info -I -M 150-dpi.pdf gives:
Retrieving info from pages 1-1...
Mediaboxes (1):
1 (6 0 R): [ 0 0 1620 5868 ]
Images (1):
1 (6 0 R): [ DCT ] 3375x12225 8bpc DevCMYK (12 0 R)
So there's your image dimensions and your media size. All you need to do is apply the division of one by the other.
Note: In debian and related distros, mutool is contained in mupdf-tools package, not in mupdf package itself. It can by therefore installed by sudo apt install mupdf-tools.
I use pdfimages -list from the poppler library, gives you all the information about the images.

I need detect the approximate location of QR code in scanned image (PDF converted to PNG)

I have many scanned document in PDF.
I use ImageMagick with Ghostscript to convert PDF to PNG in big density. I use convert -density 288 2.pdf 2.png. After that I read the pixels with PHP and find where is QR code and decode it. Because image is very big (~ 2500px), it's need very much RAM. I want, before I read pixels with PHP, to crop the image with ImageMagick and leave only that part with the QR code.
Can I detect the approximate location of QR code with ImageMagick, crop and leave only that part ?
Sample PDF
Converted PNG
Further Update
I see your discussion with Kurt about better extraction of the image from the PDF in the first place, and his recommendation was to use pdfimages. I just wanted to add that you won't find that if you do brew search pdfimages, but you actually need to use
brew install poppler
and then you get the pdfimages executable.
Updated Answer
If you change the tile size to 100x100 on the crop command and run this for the second PDF you supplied:
convert -density 288 pdf2.pdf -crop 100x100 tile%04d.png
and then use the same entropy analysis command
convert -format "%[entropy]:%X%Y:%f\n" tile*.png info: | sort -n
...
...
0.84432:+600+3100:tile0750.png
0.846019:+600+2800:tile0678.png
0.980938:+700+400:tile0103.png
0.984906:+700+500:tile0127.png
0.988808:+600+400:tile0102.png
0.998365:+600+500:tile0126.png
The last 4 listed tiles are
Likewise for the other PDF file you supplied, you get
0.863498:+1900+500:tile0139.png
0.954581:+2000+500:tile0140.png
0.974077:+1900+600:tile0163.png
0.97671:+2000+600:tile0164.png
which means these tiles
I would think that should help you pretty much approximately locate the QR code.
Original Answer
This is not all that scientific, but it may help you get started. The key, I think, is the entropy of the various areas of the image. The QR code has a lot of information encoded in a small area so it should have high entropy. So, I use ImageMagick to split the image into square 400x400 tiles like this:
convert image.png -crop 400x400 tile%03d.png
which gives me 54 tiles. Then I calculate the entropy of each of the tiles and sort them by increasing entropy, also outputting their offsets from the top left of the frame, and their name, like this:
convert -format "%[entropy]:%X%Y:%f\n" tile*.png info: | sort -n
0.00408949:+1200+2800:tile045.png
0.00473755:+1600+2800:tile046.png
0.00944815:+800+2800:tile044.png
0.0142171:+1200+3200:tile051.png
0.0143607:+1600+3200:tile052.png
0.0341039:+400+2800:tile043.png
0.0349564:+800+3200:tile050.png
0.0359226:+800+0:tile002.png
0.0549334:+800+400:tile008.png
0.0556793:+400+3200:tile049.png
0.0589632:+400+0:tile001.png
0.0649078:+1200+0:tile003.png
0.10811:+1200+400:tile009.png
0.116287:+2000+3200:tile053.png
0.120092:+800+800:tile014.png
0.12454:+0+2800:tile042.png
0.125963:+1600+0:tile004.png
0.128795:+800+1200:tile020.png
0.133506:+0+400:tile006.png
0.139894:+1600+400:tile010.png
0.143205:+2000+2800:tile047.png
0.144552:+400+2400:tile037.png
0.153143:+0+0:tile000.png
0.154167:+400+400:tile007.png
0.173786:+0+2400:tile036.png
0.17545:+400+1600:tile025.png
0.193964:+2000+400:tile011.png
0.209993:+0+3200:tile048.png
0.211954:+1200+800:tile015.png
0.215337:+400+2000:tile031.png
0.218159:+800+1600:tile026.png
0.230095:+2000+1200:tile023.png
0.237791:+2000+0:tile005.png
0.239336:+2000+1600:tile029.png
0.24275:+800+2400:tile038.png
0.244751:+0+2000:tile030.png
0.254958:+800+2000:tile032.png
0.271722:+2000+2000:tile035.png
0.275329:+0+1600:tile024.png
0.278992:+2000+800:tile017.png
0.282241:+400+1200:tile019.png
0.285228:+1200+1200:tile021.png
0.290524:+400+800:tile013.png
0.320734:+0+800:tile012.png
0.330168:+1600+2000:tile034.png
0.360795:+1200+2000:tile033.png
0.391519:+0+1200:tile018.png
0.421396:+1200+1600:tile027.png
0.421421:+2000+2400:tile041.png
0.421696:+1600+2400:tile040.png
0.486866:+1600+1600:tile028.png
0.489479:+1600+800:tile016.png
0.611449:+1600+1200:tile022.png
0.674079:+1200+2400:tile039.png
and, hey presto, the last one listed (i.e. the one with the highest entropy) tile039.png is this one.
I have drawn a rectangle around its location using this command
convert image.png -stroke red -fill none -strokewidth 3 -draw "rectangle 1200,2400 1600,2800" a.jpg
I concede there may be luck involved, but I only have one image to test my mad theories. You may need to tile twice, the second time with an x-offset and y-offset of half a tile width, so that you don't cut the QR code and split it across 2 tiles. You may need different size tiles for different size barcodes. You may need to consider the last 3-5 tiles located for your next algorithm. But I think it could form the basis of a method.

How to get Gnuplot not to crop scientific notation

I'm using gnuplot to generate the following surface plot.
The important part of the command file I'm using is:
set terminal pdfcairo size 3,3;
In particular the size 3,3 resizes the plot to the way I want but crops out part of the z-axis label in the process. If I use a wider size like size 4,3 or don't use the size option at all then the z-axis labels fit as follows:
It seems that gnuplot doesn't take the width of the label into consideration when resizing the plot.
Is there a way to maybe move the plot to the right before resizing to 3,3 so that there's room to scientific notation?
You can set the lmargin option:
set lmargin 10
(or whatever size doesn't crop the label).