Find edge of black and white image

主宰稳场 提交于 2020-03-25 17:53:46

问题


I need to find the edge and generate points of a black and white image like the one below:

I am not sure how to go about doing this. I know OpenCV is an option, but that is way overkill for what is sure to be a simple task. Does anyone know any easy way to do this? Libraries are okay, as long as they aren't too heavyweight (header only preferred)


回答1:


I would use a Canny Edge Detection, though you can easily experiment with the others that @therainmaker suggests. I would use ImageMagick which is free and installed on most Linux distros and also available for OS X and Windows.

At the command line, you would use this:

convert blob.png -canny 0x1+10%+30%  result.png

or this:

convert blob.png -canny 0x1+10%+30% -negate result.png

To use with C++, you would use Magick++, which is described here. There is a reasonable tutorial here.

If you want a description of the theory and examples of usage, including Sobel etc, please look at Anthony Thyssen's excellent pages here.

Depending on what you are actually doing, you may be better served by a Morphological technique (shape detection) rather than an Edge Detection technique. If so, ImageMagick can do that for you also. For example:

convert blob.png -morphology EdgeIn Octagon edgein.png

That technique is described nicely here.

If, you want the outline as a vector path, you can combine ImageMagick and potrace through an intermediate PBM file like this:

convert blob.png -canny 0x1+10%+30% -negate pbm:- | potrace -s -o result.svg

That will give you a nice smooth vector path like this:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
 "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="745.000000pt" height="1053.000000pt" viewBox="0 0 745.000000 1053.000000"
 preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.12, written by Peter Selinger 2001-2015
</metadata>
<g transform="translate(0.000000,1053.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M6145 8276 c-159 -39 -545 -231 -975 -485 -276 -163 -313 -179 -630
-267 -567 -157 -1108 -385 -1550 -652 -182 -111 -178 -107 -359 -289 -173
-174 -351 -387 -483 -579 -42 -61 -84 -116 -92 -123 -8 -7 -18 -25 -21 -41 -3
-16 -13 -34 -21 -41 -8 -7 -27 -33 -41 -58 -14 -25 -41 -68 -58 -96 -18 -27
-48 -81 -66 -120 -18 -38 -44 -83 -57 -100 -38 -46 -183 -353 -246 -516 -142
-373 -156 -550 -76 -979 76 -403 215 -867 299 -999 40 -62 121 -138 167 -157
58 -24 119 -32 179 -22 74 11 276 94 775 316 423 188 561 243 900 362 568 199
1059 434 1478 706 261 170 403 298 552 496 261 346 439 756 494 1138 38 261
72 696 81 1025 8 272 17 342 72 554 85 332 112 563 79 691 -49 188 -210 283
-401 236z m221 -27 c64 -30 115 -84 150 -155 28 -57 29 -64 28 -199 0 -165
-16 -262 -84 -531 -59 -229 -67 -295 -75 -569 -13 -471 -64 -995 -120 -1230
-86 -363 -361 -858 -621 -1119 -229 -229 -721 -529 -1279 -778 -220 -99 -319
-138 -615 -242 -340 -120 -556 -208 -1001 -406 -581 -260 -633 -278 -736 -259
-103 20 -207 116 -273 253 -106 221 -260 821 -301 1176 -35 311 33 578 273
1062 37 75 78 149 91 165 12 15 38 60 56 98 18 39 48 93 66 120 17 28 44 71
58 96 14 25 33 51 41 58 8 7 18 25 21 41 3 16 13 34 21 41 8 7 50 62 92 123
207 300 562 688 732 801 45 30 85 55 88 55 3 0 37 20 76 44 375 232 967 478
1521 631 268 74 353 108 535 216 333 197 793 440 927 491 143 54 243 59 329
17z"/>
</g>
</svg>



回答2:


What you are looking for is edge detection. If the image is an clean as the one posted above, the results of edge detection will be perfect, and no other processing will be needed to done after it.

So how do we do the edge detection? I'm assuming you know that an image is stored as a 2D matrix with intensity values in the computer. So, if you applied a mask over the image, i.e. take a small matrix, compute its values at different points of the image, and substitute the value at the center of the matrix by the computed result, you can do edge detection.

There are many masks for this purpose. I suggest you look at Sobell, Roberts and Prewit filters. One of the simplest filters you can use is

0  1  0
1  -4 1
0  1  0

You can do this in openCV (but I don't have much experience in it). My preferred tool is by MATLAB. You can use their inbuilt functions such as edge (here's a tutorial), or write a simple code in which you use two for loops to iterate over all pixels in the image and calculate the values applied by these filters.



来源:https://stackoverflow.com/questions/32323014/find-edge-of-black-and-white-image

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!