2

I have a raster image of a field of various size circles that I want as a vector file. The image is in high resolution and all of the circles are well defined as circles. None overlap.

Is there a way (program, plugin, etc.) to trace a bitmap image with a preset key shape? Put differently, I want to tell the program to only look for circles as it builds the vector version. The program would scan the bitmap file for anything it could recognize as a circle and only output circles.

I am interested in circles (I am trying to convert a halftone photo into a vector file) but other people might find other shapes useful.

Current findings

  • Potrace seems to do this with polygons (not circles)

  • It seems ArcGIS might allow this

  • AutoTrace seems to give a lot of control in the vectorizing process but not this

  • OCR programs can recognize circles but cannot replace them with proportional vector images.

Notes

  • I am working with thousands of dots, hand tracing is not an option

  • I saw another question on this site about trying to do something similar in Illustrator. I now cannot find the question. A person commented that Illustrator does not have shape recognition capabilities. I am not restricting my search to Illustrator.

Update: a messy workaround

In Illustrator if I use a small enough section of the image, Illustrator is able to trace all the dots, though not as circles. I then expand the appearance and select all the shapes. I use Effects > Convert to Shape > Ellipse. This does not guarantee circles, but does give ellipses. The output ellipses are much larger than the input circles and I need to judge how much to shrink them all.

0

OCR programs can recognize circles but cannot replace them with proportional vector images.

If you can recognize the circle then you can make the vector shape yourself. Just write the data to a file or use an API to a software that has a vector canvas. Or just dump the circle data into a EPS file then open it up in illustrator. Something to start

But for examle Mathematica can do this inside its toolset with no problems.

Im in a bit of a hurry as i need to get this one mechanical drawing to the machinists ASAP. SO i might write a more in depth answer later.

Simplest approach

Simplest approach is just to trace as usual, and then check if the object resembles a circle with a script. Then just replace them with the appropriate circle. Note: The OP states that he can detect them as circles. So OP should have no need for this but its the easiest solution to ship to most of you.

I have copied the heuristics form a previous post.

Now the center and shape detection is weak, it could be made better. Also it suffers from problems related to tracing in Illustrator itself. As illustrator can not easily recognize circles that have adjoining geometry flowing into them.

#target illustrator


var doc = app.activeDocument;
var objs = doc.pageItems;
traverseSceneObjects(objs, selectCircle);

//Define radius to appenf to selection


function circle_perimeter(radius){return 2 * Math.PI * radius}; 
function circle_area(radius){return Math.PI * Math.pow(radius, 2)} 

function selectCircle(item){
    var approx_radius = item.width/4+item.height/4;
    if ( compare(item.length, circle_perimeter(approx_radius)) &&
         compare(item.area, circle_area(approx_radius))
       ){
       item.selected = true;
       redraw();
       var center = item.position;
       center[0] += item.width/2.0;
       center[1] -= item.height/2.0;  
       doc.pathItems.ellipse(
       center[1]+approx_radius,center[0]-approx_radius,
              2*approx_radius, 2*approx_radius, 
              false, true
       );

       item.remove();
   }
}


function traverseSceneObjects(pageItems, func){

    for (var iter=0 ; iter<pageItems.length; iter++ ){
        var item = pageItems[iter];
        var typename = item.typename;

        // apply action or get the subitems of object
        if (typename === "PathItem"){
            func(item);


        } else if (typename === "GroupItem") {
            traverseSceneObjects( item.pageItems, func );

        } else if (typename === "CompoundPathItem" ) {
            traverseSceneObjects( item.pathItems, func );
        }

    }

}

function compare(a, b){
    return Math.abs( Math.abs(a) - Math.abs(b)) < 0.025  * Math.abs(a);
}

If one really wanted then one should make a circle Hough transform to find the circles. Then just paintt them directly. But I dont have time for that now, also it requires quite much more setup on readers part. USe openCV, matlab or mathematica for this.

Anyway the above script does work on all freestanding circles in my 3 test drawings. But obviously theres infinite potential to fail also.

  • Does this apply to an image full of many circles? Or would it be circle by circle as different files? – Unrelated Jan 17 '18 at 17:07
  • @Unrelated no one file with all the circles. Or actually vector files are just that lists of primitives. Most vector formats are actually just text (SVG, PDF, and EPS certainly are.) – joojaa Jan 17 '18 at 17:52
  • @joojaa I hope you end up writing a more in depth answer ;) – Zach Saucier Jun 16 '18 at 12:17
  • @ZachSaucier ok is it enough that i turn near circles into circles because that much more shippable, – joojaa Jun 16 '18 at 16:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.