3

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>
Jason
  • 73
  • 1
  • 7
  • Try `convert +antialias input.svg output.png` with **ImageMagick** – Mark Setchell Jan 03 '19 at 22:22
  • antialias did not fix this problem, it does seem to reduce the effect somewhat – Jason Jan 03 '19 at 22:35
  • Maybe you could add a complete, simple SVG to test with, please. Also please show your ImageMagick version, i.e. output of `identify -version` – Mark Setchell Jan 03 '19 at 22:40
  • Version: ImageMagick 7.0.8-22 Q16 x86_64 2018-12-31 https://imagemagick.org Copyright: © 1999-2019 ImageMagick Studio LLC License: https://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 zlib – Jason Jan 03 '19 at 22:42
  • I was thinking `-interpolate integer` would be the solution but it also does not fix the problem. – Jason Jan 03 '19 at 23:05
  • Can you describe in a bit more detail what you are trying to do please? How many polygons might you typically have? How many different colours? How many different opacities? – Mark Setchell Jan 03 '19 at 23:48
  • There can be any number of polygons, however they can only be of greyvalues 221 or 50, with overlaps being 160. The problem is that when rasterizing algorithms were interpolating values along the edges as other greyvalues throwing off the object detection. ccprog solved this by adding the SVG element `shape-rendering="crispEdges"`. – Jason Jan 04 '19 at 16:56

2 Answers2

3

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

fmw42
  • 46,825
  • 10
  • 62
  • 80
  • This does not solve the problem of interpolated pixel values on the edges. If you zoom into the images created by your examples you will see that the edges are still blurred. – Jason Jan 03 '19 at 23:35
  • Zooming will cause jagged edges if you zoom by pixel replication past the full size of the image. What you are seeing by zooming is pixels along the line with the anti-aliasing. Pixels are discrete and lines at diagonals are always jagged at the pixel level even with anti-aliasing. You will get better quality if you use my last method and enlarge by setting the density. See the last example I posted as an ADDITION where I used density 1200. It is smooth unless you zoom past this full resolution size. – fmw42 Jan 04 '19 at 00:53
3

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.

ccprog
  • 20,308
  • 4
  • 27
  • 44