Eliminate large clumps with gdal_sieve? - gdal

I have a raster dataset and have used gdal_sieve to eliminate clumps of pixels made up of below a certain number of pixels. How do I eliminate large clumps of pixels above a certain number of pixels?

gdal_sieve.py does not support removing objects above a threshold size. However it seems that your desired output can be achieved by sieving objects below your threshold and then calculating the difference between the input and sieved images:
gdal_sieve.py -st <<threshold>> input.tif sieved.tif
gdal_calc.py -A input.tif -B sieved.tif --calc="A ^ B" --outfile=output.tif

Related

How to apply custom halftone to ghostscript conversion of PDF file to bitmap

I have a PDF file with a grayscale image that I'm trying to convert to monochromatic bitmap (1 bit per pixel) using ghostscript. I can get everything to work fine, but I don't like the way the default grayscale conversion looks with coarse lines going through it. My understanding is that I can customize the halftone algorithm to my liking, but I can't seem to get the postscript commands to have an effect on the output. Am I using the 'sethalftone' command incorrectly? Is there a different approach I should consider?
gs -sDEVICE=bmpmono -sOutputFile=test.bmp -dBATCH -dNOPAUSE -r300 -c "<< /HalftoneType 1 /Frequency 40 /Angle 0 /SpotFunction {pop}>> sethalftone" -sPageList=1 input.pdf
I can completely remove the "-c" command line parameter and it makes no difference.
This is what the current mono conversion looks like that I'm trying to improve upon:
Using the default halftone built into Ghost Script has a limited working range and a tendency to provide an appearance leaning to one side, (it is deliberate design not accidental) there is a dither control but that tends to work effectively at r/20 to r/5 in this case showing -dDITHERPPI=25 to -dDITHERPPI=60 thus reducing the blocks in size. However there are other potential controls.
I am no expert on how these settings are best used (plagiarized) we would need to read the PS manual, or play with their values, but they seem to fare better.
gswin32c -sDEVICE=bmpmono -r300 -o out.bmp -c "<< /Frequency 133 /Angle 45 /SuperCellSize 36 /Levels 255 >> .genordered /Default exch /Halftone defineresource { } settransfer 0.003 setsmoothness" -f ../examples/text_graph_image_cmyk_rgb.pdf
(note you may wish to include -dUseFastColor before -c "....)
Changing values
/Angle common values may be 0 (0=GS default) 22 30 45 52 60 67 however /Angle 45 is most common for this mono conversion, and variations coupled with a range of /Frequency (Line Screen Frequency ~= LPI) and SuperCell size may produce unachievable or sub normal result.
/Frequency (75=GS default) can be set to different values but a common ratio is 4/3 = 133 (%) another is 170 however a rule of thumb is r/2 thus if your using 300dpi /Frequency 150 may be better in this case. The correct choice is down to a complex consideration of factors, so your grid at 45 degrees is spaced at sqrt(2)=1.41421356237 at an angle. Thus the horizontal & vertical effect is 0.7071....(in terms of page dpi) thus to match 300 dpi the LPI frequency needs to be possibly made relative so consider 212
/SuperCellSize eludes me Integer; default value = 1 -- actual cell size determined by Frequency, Angle, H/V Resolution. A larger value will allow more levels to be attained. Unclear as to what may be optimum without sample of target, so try a few values but some will trigger error feedback try around 32 or 64 as a reasonable max start point. note example uses 36 ?
To prevent the undesirable moire patterns, Peter Fink proposed the Supercell Method named the Adobe Accurate Screen to realize the screen
angle having RT with the required accuracy.3 The supercell designed in the image domain including m × m (m: integer) identical halftone cells is one solution to approximate accurately the required screen angle and screen ruling. https://www.imaging.org/site/PDFS/Papers/1998/PICS-0-43/668.pdf
You may also wish to try
/DotShape Integer; default value = 0 (CIRCLE). Other shapes available are:
1=REDBOOK, 2=INVERTED, 3=RHOMBOID, 4=LINE_X, 5=LINE_Y, 6=DIAMOND1, 7=DIAMOND2, 8=ROUNDSPOT,
These values and more can be found at https://ghostscript.com/doc/current/Language.htm
Upper Left is a mono area dithered in a graphics app where depending on resolution and density "worms" or "moire" patterns start to appear. To regulate such effects a deliberate screen is applied and at smallest units aberration's in the linework pattern will not be noticeable, unless zoomed beyond intended scrutiny.
gswin32c -sDEVICE=bmpmono -r300 -o out.bmp -c "<< /Frequency 106 /Angle 45 /SuperCellSize 64 /Levels 255 >> .genordered /Default exch /Halftone defineresource { } " -f test.pdf
Imagemagick can use custom halftones, defined by XML files, so if you can't get the result you need directly with GhostScript, another option is to use GhostScript to output a high-resolution greyscale image, and use Imagemagick to produce the black and white halftoned image.

How to perform non-maximum supression of keypoints conditioned on another channel

The standard non maximum suppression or finding peaks in a 2D image involves two steps:
Do a max pool with a kernel size, as maxpooled_image.
Then select the pixels where pixel_value == maxpooled_image value
However, let us say I have an additional channel, value2. Consider two strong pixels that belong in one NMS window. Now, in the standard case, only one of these pixels will be chosen. However, I'd like to add an additional condition that if the value2 are sufficiently different by some threshold (dth), then select both pixels, but if the difference between the value2 value of pixel1 and pixel2 is small, then pick only the brighter pixel.
How do I achieve this? in numpy

How to make gnuplot generate figures with smaller/fized size (Bytes)?

I would like to avoid using every command since it simply discards data that, however, might be very important (like a spike for instance). I would like also to avoid posterior downsizing since this might lead to the deterioration of the text on the figure...
Is there a manner/option to force gnuplot generating files (eps) with maximum size?
You'd need some adaptive compression on your data. Without actually knowing it, that's rather tough.
The stats command can tell you how many datapoints you actually have, and you can then adjust the every statement to a sensible value. Otherwise, you can use smooth to achieve a predefined (set sample) number of datapoints, or (if you have a sensible model for you data) you can do a fit and simply plot the fitted model function instead of you dataset.
If you specifically want outliers to show in the plot, this might be helpful:
fit f(x) data via *parameter*
plot f(x), data using ((abs($2-f($1)) > threshold) ? $2 : NaN)
It plots a fit to your dataset, and all actual datapoints that deviate from the fit by more than threshold.

Animated GIF larger than source images

I'm using imagemagick to create an animated GIF out of ~60 JPG 640x427px photos. The combined size of the JPGs is about 4MB.
However, the output GIF is ~12MB. Is there a reason why the GIF is considerably bigger? Can I conceivably achieve a GIF size of ~4MB?
The command I'm using is:
convert -channel RGB # no improvement in size
-delay 2x10 \
-size 640 \
-loop 0 \
-dispose Background # no improvement in size
-layers Optimize # about 2MB improvement
portrait/*.jpg portrait.gif
Using gifsicle didn't seem to improve either.
JPG is lossy compression.
GIF is lossless compression.
A better comparison would be to convert all the source images to GIF first, then combine them..
First google hit for GIF compression is http://ezgif.com/optimize which claims lossy GIF compresion, might work for you but I offer no warranty as I haven't tried it.
JPEG achieves it's compression through a (lossy) transform, where an 16x16 / 8x8 block of pixels is transformed to frequency representation and then quantized. Instead of selecting e.g. 256 levels (i.e. 8 bits) of red/green/blue per component, JPEG can ignore some frequency components, or use just 1 or 2 bits to represent them.
GIF on the other hand works by identifying repeated patterns from a paletted image (upto 256 entries), which occur exactly in the previously encoded/decoded stream. Both because of the JPEG compression, and the source of the images typically encoded by JPEG (natural full color), the probability of (long) exact matches is quite low.
60 RGB images with the size 640x427 is about 16 million pixels. To represent that much in 4 MB, requires a compression of 2 bits per pixel. To achieve this with GIF would require a very lossy algorithm, that would select (vector) quantization of true color pixels not to the closest pixel in the target GIF palette, but based also on the fact how good dictionary of code words this particular selection will make. The dictionary builds slowly and to achieve 2 bits/pixel, the average length of the decoded code word would have to map to 5.5 matching pixels in the close neighborhood.
By contrast, imagemagick has been able to compress the 16 million pixels (each selected from a palette of 256 elements) to 75% already!

Is there any available DM script that can compare two images and know the difference

Is there any available DM script that can compare two images and know the difference?
I mean the script can compare two or more images, and it can determine the similarity of two images, for example the 95% area of one image is same as another image, then the similarity of these two images is 95%.
The script can compare brightness and contrast distribution of images.
Thanks,
This question is a bit ill-defined, as "similarity" between images depends a lot on what you want.
If by "95% of the area is the same" you mean that 95% of the pixels are of identical value in images A & B, you can simply create a mask and sum() it to count the number of pixels, i.e.:
sum( abs(A-B)==0 ? 1 : 0 )
However, this will utterly fail if the images A & B are shifted with respect to each other even by a single pixel. It will also fail, if A & B are of same contrast but different absolute value.
I guess the intended question was to find similarity of two images in a fuzzy way.
For these, one way is to do crosscorrelation. DM has this function. Like this,
image xcorr= CrossCorrelate(ref,img)
From xcorr, the peak position gives x- and y- shift between the two, the peak intensity gives "similarity" of the two.
If you know there is no shift between the two, you can just do the sum and multiplication,
number similarity1=sum(img1*img2)
Another way to do similarity is calculate Euclidian distance of the two:
number similarity2=sqrt(sum((img1-img2)**2)).
"similarity2" calculates the "pure" similarity. "similarity1" is the pure similarity plus the mean intensity of img1 and img2. The difference is essentially this,
(a-b)**2=a**2+b**2-2*a*b.
The left term is "similarity2", the last term on the right is the "crosscorrelation" or "similarity1".
I think "similarity1" is called cross-correlation, "similarity2" is called correlation coefficient.
In example comparing two diffraction patterns, if you want to compute the degree of similarity, use "similarity2". If you want to compute the degree of similarity plus a certain character of the diffraction pattern, use "similarity1".