# Line Drawing

## Recommended Posts

I just need to keep this somewhere until I can get back to it. It is totally unfinished.

##### Share on other sites

• 3 weeks later...

Your filter does edge detection + binarization. I attached the result of your code without thresholding, and the result of mine.

I didn't publish it yet, but basically it implements the sobel operator ( http://en.wikipedia.org/wiki/Sobel_operator ).

I was wondering how you got that idea of computing some kind of gradients using gaussian blur ?

##### Share on other sites

My goal has always been to create an effect that creates a line drawing from a photograph. So, that's why I put the threshold code in. I'm more interested in focusing on the edges and throwing out all other information (gradients/shading).

I was wondering how you got that idea of computing some kind of gradients using gaussian blur ?

The idea for this effect just naturally occured to me when looking at the unsharp mask code that Tanel gave me for my Landscape plugin. I figured that when you Gaussian blur an image, the amount of change a pixel has between the original source canvas and the blured image would show you how likely an edge has been found. I, honestly, didn't know it had a name.

As you can see from my output, I need to really think through how to compute the difference to improve the output. I have a long way to go before it produces good looking results.

BTW, funny, but when I first wrote the effect, it turned out white lines on a black canvas, just like the sample image in the wikipedia article you linked.

##### Share on other sites

Yes, that's what my code does too, i inverted the output, to make it easier too compare to your output.

Actually, gradients are vectors whos direction indicates the direction of the highest rate of change, and whose magnitude indicates the strength of the changes.

If you set pixel values to the magnitude, you get i picture like mine, but with edge in white.

Your technique detects edges because gaussian blur average colors around one pixel, so if you have a uniform area, the average tends to keep a close value to the original, but if you have an edge, the color is much more affected by different colors surronding it, so when you compute the difference, you can see edges.

Sounds like an esoteric technique, but works

I think what you want is a canny edge detector.

It's like a 20y.o. cutting edge edge detector.

First, you apply a gaussian blur to take out high frequency noise. Second then you apply a simple edge detection algo like sobel, or something else. Then you apply one more pass that takes out non maximum edges. Then there's a step called thresholding with hysteris (i didn't try to find out this step, but it can't be so hard, that gets you your binary picture).

http://en.wikipedia.org/wiki/Canny_edge_detector

##### Share on other sites

Here is what a got with a canny edge detector on that picture (it's a bit downscaled).

I used the tool at http://matlabserver.cs.rug.nl/

##### Share on other sites

Interesting, but not what I'm after.

Now, if you take my image above and run Effects > Noise > Median (1/50)...

That's more of what I'm shooting for.

##### Share on other sites

I get something similar by removing edge thining and changing thresholds.

##### Share on other sites

Yeah, I'm looking for something that can draw a picture like my avatar from a photograph. Simple, fat lines of uniform size without random stray pixels. The color fills are not necessary. They can be done later by hand.

The "canny edge" effect looks close, but the lines are too thin and the image is too busy.

My closest to date is Ink Sketch (or Ink Sketch followed by a Median blur). But, I'm always looking to improve the output.

Tweeks:

```// Author: BoltBait
// Name: Line Drawing
// URL: [url=http://www.BoltBait.com/pdn]http://www.BoltBait.com/pdn[/url]
#region UICode
int Amount1 = 10; // [1,20] Tinker
int Amount2 = 10; // [1,20] Radius
#endregion

// Rick, stop moving stuff around
private byte Clamp2Byte(int iValue)
{
if (iValue<0) return 0;
if (iValue>255) return 255;
return (byte)iValue;
}

unsafe void Render(Surface dst, Surface src, Rectangle rect)
{
Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

// Setup for calling the Blur function
GaussianBlurEffect blurEffect = new GaussianBlurEffect();
PropertyCollection bProps = blurEffect.CreatePropertyCollection();
PropertyBasedEffectConfigToken bParameters = new PropertyBasedEffectConfigToken(bProps);
blurEffect.SetRenderInfo(bParameters, new RenderArgs(dst), new RenderArgs(src));
// Call the Blur function
blurEffect.Render(new Rectangle[1] {rect},0,1);

// Now in the main render loop, the dst canvas has a blurred version of the src canvas
for (int y = rect.Top; y < rect.Bottom; y++)
{
for (int x = rect.Left; x < rect.Right; x++)
{
ColorBgra SourcePixel = *srcPtr;

double RDiff, GDiff, BDiff;

// Similar to UnSharp Mask here...
RDiff = Math.Abs((double)SourcePixel.R - (double)AdjustmentPixel.R) * ((double)Amount1 / 100.0);
GDiff = Math.Abs((double)SourcePixel.G - (double)AdjustmentPixel.G) * ((double)Amount1 / 100.0);
BDiff = Math.Abs((double)SourcePixel.B - (double)AdjustmentPixel. * ((double)Amount1 / 100.0);

// Add up all the differences
adj = Clamp2Byte((int)(RDiff + GDiff + BDiff));

// Change the pixel to black or white depending on a threshold amount
adj = ((adj > Amount1) || (RDiff > (Amount1/3)) || (GDiff > (Amount1/3)) || (BDiff > (Amount1/3)))? (byte)0 : (byte)255;

// I should probably use alpha in the final algorithm, but for for now, just set it to full

// Show it

srcPtr++;
dstPtr++;
}
}
}```

##### Share on other sites

I'm looking for something that can draw a picture like my avatar from a photograph. Simple, fat lines of uniform size without random stray pixels. The color fills are not necessary. They can be done later by hand.

I don't know if my different take on this is worth pursuing, but rather than identifying the edges, why not try to identify the spaces in between?

Had I the ability, I'd take the photo and posterize it into lumps of color first then look at the width of the borders in between.

##### Share on other sites

I can get that, but it's not as perfect as your avatar.

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×