BoltBait Posted February 20, 2010 Share Posted February 20, 2010 I just need to keep this somewhere until I can get back to it. It is totally unfinished. Quote Click to play: Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game Link to comment Share on other sites More sharing options...
zarathoustra Posted March 11, 2010 Share Posted March 11, 2010 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 ? Quote Link to comment Share on other sites More sharing options...
BoltBait Posted March 11, 2010 Author Share Posted March 11, 2010 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. Quote Click to play: Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game Link to comment Share on other sites More sharing options...
zarathoustra Posted March 11, 2010 Share Posted March 11, 2010 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 Quote Link to comment Share on other sites More sharing options...
zarathoustra Posted March 11, 2010 Share Posted March 11, 2010 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/ Quote Link to comment Share on other sites More sharing options...
BoltBait Posted March 11, 2010 Author Share Posted March 11, 2010 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. Quote Click to play: Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game Link to comment Share on other sites More sharing options...
zarathoustra Posted March 11, 2010 Share Posted March 11, 2010 I get something similar by removing edge thining and changing thresholds. Quote Link to comment Share on other sites More sharing options...
BoltBait Posted March 12, 2010 Author Share Posted March 12, 2010 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); bParameters.SetPropertyValue(GaussianBlurEffect.PropertyNames.Radius, Amount2); 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++) { ColorBgra* srcPtr = src.GetPointAddressUnchecked(rect.Left, y); ColorBgra* dstPtr = dst.GetPointAddressUnchecked(rect.Left, y); for (int x = rect.Left; x < rect.Right; x++) { ColorBgra AdjustmentPixel = *dstPtr; ColorBgra SourcePixel = *srcPtr; double RDiff, GDiff, BDiff; byte adj; // 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; AdjustmentPixel.R = AdjustmentPixel.G = AdjustmentPixel.B = adj; // I should probably use alpha in the final algorithm, but for for now, just set it to full AdjustmentPixel.A = 255; // Show it *dstPtr = AdjustmentPixel; srcPtr++; dstPtr++; } } } Quote Click to play: Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted March 12, 2010 Share Posted March 12, 2010 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. Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
zarathoustra Posted March 12, 2010 Share Posted March 12, 2010 I can get that, but it's not as perfect as your avatar. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.