3
votes

I need to convert images for object detection. I start with svg images with multiple polygons. Example:

<svg ...>
<rect width = "100%" height = "100%" fill = "rgb(0,0,0)" />
<polygon points="..." fill="rgb(221,221,221)" fill-opacity="1.0" />
<polygon points="..." fill="rgb(100,100,100)" fill-opacity="0.5" />
</svg>

The result is a black background, object A having color rgb(221,221,221), object B having color rgb(50,50,50), and anywhere the two objects overlap rgb(160,160,160). The detection algorithm (cannot be modified) determines objects by their pixel values.

I have successfully converted from svg to png using inkscape, svgr-convert, or ImageMagikk. However the edges of these png images are always blurry which in interfering with my object detection.

Is there some way to convert having crisp edges? This image shows the conversion adding blurred pixels with incorrect values. I have zoomed into an edge to make it obvious.

edit: full image example

<svg viewBox="17.874 6.66874 74.0131 70.817" xmlns="http://www.w3.org/2000/svg">
<rect width = "100%" height = "100%" fill="black" fill-opacity="1.000000" stroke="black" stroke-opacity="1.000000" stroke-width ="0.000000"/>
<polygon points="66.499391,34.862972 35.730400,51.495089 68.667463,64.499553 " fill="rgb(221,221,221)" fill-opacity="1.000000" />
<polygon points="47.613765,49.254424 23.219703,52.458598 47.246912,50.965952 48.078815,51.599703 49.620943,52.471096 62.516253,65.471290 65.077318,43.877861 51.086443,12.014429 34.861708,20.532821 " fill="rgb(100,100,100)" fill-opacity="0.500000" />
</svg>
2
Try convert +antialias input.svg output.png with ImageMagickMark Setchell
antialias did not fix this problem, it does seem to reduce the effect somewhatJason
Maybe you could add a complete, simple SVG to test with, please. Also please show your ImageMagick version, i.e. output of identify -versionMark Setchell
Version: ImageMagick 7.0.8-22 Q16 x86_64 2018-12-31 imagemagick.org Copyright: © 1999-2019 ImageMagick Studio LLC License: imagemagick.org/script/license.php Features: Cipher DPC HDRI Modules Delegates (built-in): bzlib freetype jng jp2 jpeg lcms ltdl lzma png tiff webp xml zlibJason
I was thinking -interpolate integer would be the solution but it also does not fix the problem.Jason

2 Answers

3
votes

Add the attribute in the <svg> element ( it's inherited by all child elements)

shape-rendering="crispEdges"

While from my short test Inkscape seems not to honor that, rsvg-convert does. For your Imagemagick setup, you should make sure it delegates to librsvg, not Inkscape.

1
votes

What you need to do is increase the density when reading your SVG file. You can either increase the density by some factor and save that result or you can increase the density by the factor and then resize by the inverse factor. The default density for SVG is 96 dpi. So in Imagemagick 6 the basic command would be:

convert test.svg test.png


enter image description here

which is the same as

convert -density 96 test.svg test1.png


enter image description here

Now you can increase the density by 4 to 384.

convert -density 384 test.svg test2.png


enter image description here

or for larger images with line drawings that you need to preserve at the original resolution, you can resize down by 1/4 or 25%

convert -density 384 test.svg -resize 25% test3.png


enter image description here

For Imagemagick 7, change convert to magick.

ADDITION:

Here is a version enlarged using density 1200, which will look smooth unless you zoom beyond the full resolution.

convert -density 1200 test.svg test4.png


enter image description here