Fitting a curve to a drawing in Gimp - gimp

I'd like to make a logo which contains some mathematically defined shapes (to wit, a log-normal and normal distribution; see below). I can generate an image of these shapes using Python's Matplotlib, but I would like to import this into Gimp.
In Gimp, I'm aware of the tool for drawing Bezier curves by hand, as well as the 'select by color' option which could be used to select the curves. However, I'd like the lines to be a constant thickness. Is there a way to 'fit' two constant-thickness lines to a picture like this in Gimp?

If you have them as Paths (in other words, Bezier curves) just "stroke" them (Edit>Stroke path if done manually, pdb.gimp_edit_stroke_vectors(layer,path) in Python).

Related

Draw gradient along a path in iOS

I've found quite a few sample that archived kind of a similar result, but what I want is to draw a multi-line gradient along an arbitrary path. (I need it to visualize users speed during a run on a MapView)
So the gradient will have quite a few colors and colorLocations.
What I've see so far is one gradient and this one is masked to a path. But that's not what I need.
So the result I want it something like the Nike Runners Club App. They draw a beautiful gradient.
So it should look something like this:

Vectorization of binary grayscale image

I have binary grayscale bitmap images (black and white) that contain lines, curves and some simple shapes (ellipses, and polygones), my goal is to describe these elements as formulas.
One of the options is to apply vectorization on the images, but I am not expert in this domain so I need your help in suggesting what can I do. is there any tool or library that is able to provide the formulas that describe these objects?
Thank you
Perhaps cubic bezier is what you need:
This is a project I've done, (1) I use Ramer-Douglas-Peucker to remove noise and (2) represent the curves as cubic bezier I obtain by using least square fitting:
This is original drawing:
Vectorized image:
Since it's already converted to mathematical formula, It can be zoomed infinitely.
Sorry I can't share the code since it's quite enormous but I hope you get the idea.
If you want tracing library you can use this: http://potrace.sourceforge.net/
Also If you're interested to only remove noise you can try CSS: http://www.morethantechnical.com/2012/12/07/resampling-smoothing-and-interest-points-of-curves-via-css-in-opencv-w-code/
If you have nice proper uninterrupted shapes you can just trace their contours using something like findContours().. But if your input (that you did not describe properly) is noisy and sketchy, the approach should rely on a Hough transform, see below. By the same coin, in fitting curves a lot will depend on the level of noise and the presence of outliers (e.g. background elements that aren't shapes or are inaccurate shapes that only approximate, say a proper ellipse). It is hard to imagine proper clean lines and proper shapes in a typical task unless it is a homework.
Hough lines and Hough circles are the most widely used functions in openCV library. Note that fitting ellipses is non-trivial since they have 5 parameters (lines have 2 and circles have 3) and Hough space grows too much. Rectangles can be found either with Hough lines or a special rectangle Hough. Other shapes can be detected using generalized non-parametric Hough.
Fitting curves should use RANSAC to get rid of outliers, and geometric (least square in terms of point distances) fit to minimize pixel noise. The latter procedure typically involves non-linear optimization that should be initialized by a simpler algebraic fit. Luckily, for simple geometric primitives fitting functions have already been written, see fitLine().
The bottom line, given that your shapes are a bit noisy, your task is non-trivial (to the degree you probably don't realize) and thus should be split on several sub-projects like finding shapes, fitting curves, etc.

Recognize basic shapes in binarized image using OpenCV

How can I recognize some basic (usually rotated) shapes:
circle,
"empty" circle,
cross,
empty triangle,
using OpenCV? What's the most straightforward way? It would be nice if the user could "define" his own shapes somehow (load a template image, possibly).
I'd like to map each recognized shape to its type (circle, triangle etc.) and a position of its center. (And its rotation if possible).
For circles HoughCircles could be used (there's no rotation in this case, too). But what about the others? Template matching doesn't support rotation and scaling, right?...
Here's the input:
You are right that regular template matching are not rotation, scale invariant. Take a look at OpenCV's matchShapes. Internally, it uses HuMoments. You will need to use findContours to find each individual object. Now once you have done this, you will probably find matchShapes couldn't distinguish Circle from Ring. A simple way to solve this is to use the hierarchy structure from findContours. If there is a hole (large enough) inside a Circle, that's probably a Ring.

Extract coordinates from image file

How to get an array of coordinates of a (drawn) line in image? Coordinates should be relative to image borders. Input: *.img . Output array of coordinates (with fixed step). Any 3rd party software to do this? For example there is high contrast difference - white background and color black line; or red and green etc.
Example:
Oh, you mean non-straight lines. You need to define a "line". Intuitively, you might mean a connected area of the image with a high aspect ratio between the length of its medial axis and the distance between medial axis and edges (ie relatively long and narrow, even if it winds around). Possible approach:
Threshold or select by color. Perhaps select by color based on a histogram of colors, or posterize as described here: Adobe Photoshop-style posterization and OpenCV, then call scipy.ndimage.measurements.label()
For each area above, skeletonize. Helpful tutorial: "Skeletonization using OpenCV-Python". However, you will likely need the distance to the edges as well, so use skimage.morphology.medial_axis(..., return_distance=True)
Do some kind of cleanup/filtering on the skeleton to remove short branches, etc. Thinking about your particular use, and assuming your lines don't loop around, you can just find the longest single path in the skeleton. This is where you can also decide if a shape is a "line" or not, based on how long the longest path in its skeleton is, relative to distance to the edges. Not sure how to best do that in opencv, but "Analyze Skeleton" in Fiji/ImageJ will let you filter by branch length.
What is left is the most elongated medial axis of the original "line" shape. You can resample that to some step that you prefer, or fit it with a spline, etc.
Due to the nature of what you want to do, it is hard to come up with a sample code that will work on a range of images. This is likely to require some careful tuning. I recommend using a small set of images (corpus), running any version of your algo on them and checking the results manually until it is pretty good, then trying it on a large corpus.
EDIT: Original answer, only works for straight lines:
You probably want to use the Hough transform (OpenCV tutorial).
Python sample code: Horizontal Line detection with OpenCV
EDIT: Related question with sample code to skeletonize: How can I get a full medial-axis line with its perpendicular lines crossing it?

How to implement a Photoshop Curves editor in UIKit

I'm familiar with UIBezierPath and the corresponding CG routines, but none of them appear to draw the same type of path as what I see in Photoshop, etc.
How would one go about this? I'm just talking about the UI--letting the user drag around points.
A java example I found is here: http://www.cse.unsw.edu.au/~lambert/splines/natcubic.html
I would look into CGContextAddCurveToPoint and drag around curve's control points. If you require more control points to create a complex curve, just split a resulting curve into simple segments.
Take a look at this article It explains how to calculate the control points based on knots you have on your curve.

Resources