开发者

cartoonizing real images

does anybody know we can translate from real image captured using cameras be converted to the cartoon space ?

Please note that my goal is not to create animations or the likes, but just to translate to "cartoon colors" if possible.

will simple requantization to a space where there is less quantization levels work Or some other specific transforms are better ?

any h开发者_开发技巧elp will be useful, as I wasn't able to find any material on this.

Thnx in advance.


Pyramid mean shift + outline of detected edges seems does the job.

The code:

cv::Mat segmented, gray, edges;
cv::pyrMeanShiftFiltering(input, segmented, 15, 40);
cv::cvtColor(segmented, gray);
cv::Canny(gray, edges, 150, 150);
cv::cvtColor(edges, edgesBgr, CV_GRAY2BGR);
cv::Mat result = bgr - edgesBgr;

Here is a result i got:

cartoonizing real images

Details: OpenCV Tutorial Part 6


What you're trying to do is most commonly done from 3D models and is called cel-shading, or "toon-shading". Basically, you try to force uniform colors and force abrupt transitions at certain angles with respect to the light source.

Obviously, this does not translate well to 2D input images. What you can do, is to requantize but making sure you uniformly fill regions and break where the image gradient is high.

Non-linear diffusion is a denoising technique that forces regions to become uniform to remove noise. If you let it loop for too many iterations, you get a cartoon-looking image.

I've implemented that maybe 2-3 years ago and it worked suprisingly well considering it was not so hard to implement. However, you're going to want a GPGPU implementation because it is slow!


You could also take a look at mean shift segmentation. An implementation is available here: EDISON


Complete shot in the dark:

  1. Convert to HSV color space (cvtColor using CV_BGR2HSV)
  2. Leave H(ue) alone, or quantize it down to some smaller set if you want
  3. Binary threshold S(aturation) with a low threshold so that pastels push to white
  4. Binary threshold V(alue) with a low threshold so that dark stuff turns to black

Absolutely untested. Probably speaking out of my hat... But should be pretty low CPU use if it would work. This strikes me as the sort of thing to fire up with sliders for the values needed in steps 2-4 and just fiddle with it.

EDIT: A friend pointed out that you might also want lines around objects. My first thought for that would be to use cvCanny to pick out edges (requires a grayscale image... I'm not sure if it would be better to do this before or after the HSV cartooning. Probably before). Those will be a single pixel wide, which may not be enough, so you may want to dilate them a bit to widen them up. They'll be white on a black background, so you can then subtract them from your cartoon colored image, which will pull the pixels where the lines are down to 0 (saturation arithmetic to the rescue) but leave the other pixels alone.


Your term "cartoon space" made me think that perhaps you should start from that idea:

  1. Create a cartoony colourspace that you like with perhaps 20-30 nice bright colours that cover most of the regular RGB space but have a bright/shiny theme (or whatever cartoony colour-theme you like).
  2. Requantize your image, not to a subset of the available colours in the image but to the colours in your cartoony colourspace (i.e. match each colour to the nearest colour in your cartoon colourspace).
  3. Bonus points: Eliminate small coloured regions to get a more uniform single colour look.
  4. More bonus points: add black outlines to each single-coloured region for extra cartoonishness. Perhaps vary line-thickness with the gradient in the original image.
  5. Optional tweak: Convert all your colours to the HSV colourspace, perform step 2 only on the Hue channel for extra shadow immunity.


It's relatively easy to do. Here are the steps:

  • bilateral filtering to simplify/abstract the photo. You may want to separate the bilateral filter so that it's faster. Perform the bilateral filter in 1d along the gradient and then along the normal to the gradient.
  • detect the edges. For instance, using a Difference of Gaussians algo. You may want to use the DoG in the gradient direction and smooth it following the flow lines. To get the flow lines, you would need to get the Edge Tangent Flow (ETF) which you can get via structure tensor.
  • quantize the colors. Actually, you quantize the luminance to simulate cel shading aka toon shading.
  • blend the abstracted image afer quantize and the edges you detected.

I put some free software (for win64) that does exactly this at http://3dstereophoto.blogspot.com/p/painting-software.html. It's called "The Cartoonist".

If you want to see "The Cartoonist", have a look at http://3dstereophoto.blogspot.com/2018/07/non-photorealistic-rendering-software_9.html. It shows all the steps with an example.

To be clear, those are links to my blog which primarily deals with 3d photography (depth maps, photogrammetry, etc). I love painting though and I also do research in image-based non photorealistic rendering (npr).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜