图像分类 - 检测图像是卡通式的

时间:2009-10-05 04:50:12

标签: image-processing

我有大量的JPEG缩略图,大小从120x90到320x240不等,我想将它们分类为真实生活或卡通式。

如何使用ImageMagick的实用程序执行此操作:convertcompareidentify?或者还有其他程序可以解决这个问题吗?

4 个答案:

答案 0 :(得分:16)

我猜你最好的位是直方图和像素数之间的无线电。卡通线图像趋势的颜色数量少于现实颜色。

您可以使用

COLORS=`convert picture.jpg  -format %c histogram:info:- | wc -l`

计算图片的颜色数量。并使用如下命令:

WIDTH=`jpeginfo picture.jpg | sed -r "s/.* ([0-9]+) x.*/\1/"`

HEIGHT=`jpeginfo picture.jpg | sed -r 's/.*x ([0-9]+)  .*/\1/'`

提取宽度和高度。

然后使用此命令查找比率:

echo $WIDTH $HEIGHT $COLORS | awk '{ print $3/($1 * $2);}'

然后由你来定义什么比例是合格的卡通和什么不合格。 对于像卡通一样,这个比例大多低于现实生活中的比例。

只是一个想法。

编辑:我刚刚看到你的评论,你不想知道如何退出。那么就忽略我的答案。

编辑2:我稍微修改一下以便于查看。

注意1:你应该注意到我交换了比率,因为像素数总是远远大于颜色数,所以之前的程序导致 较低的数字。这就是为什么你难以区分它们。

注2:我也从“jpeginfo”更改为“identity”,因为jpeginfo只能执行jpg而且它不是ImageMagick的一部分。

〜/测试/ CheckCartoon.sh

#!/bin/sh

IMAGE=$1 COLORS=convert $IMAGE -format %c histogram:info:- | wc -l WIDTH=<b>identify</b> $IMAGE | sed -r "s/.* ([0-9]+)x[0-9]+ .*/\1/" HEIGHT=<b>identify</b> $IMAGE | sed -r 's/.* [0-9]+x([0-9]+) .*/\1/' RATIO=echo $WIDTH $HEIGHT $COLORS | awk '{ print <b>($1 * $2)/$3</b>;}' echo $RATIO | awk '{ printf "%020.5f",$1 }'

〜/测试/ CheckAll.sh

convert $IMAGE -format %c histogram:info:- | wc -l

现在测试你在这里复制文件。

图1:~/test/images/Cartoon-01.jpg

图2:~/test/images/Cartoon-02.png

图3:~/test/images/Cartoon-03.gif

图4:~/test/images/Real-01.jpg

图5:~/test/images/Real-02.jpg

图6:~/test/images/Real-03.jpg

http://dl.getdropbox.com/u/1961549/StackOverflow/SO1518347/Images.png

然后我运行<b>identify</b> $IMAGE | sed -r "s/.* ([0-9]+)x[0-9]+ .*/\1/"(在<b>identify</b> $IMAGE | sed -r 's/.* [0-9]+x([0-9]+) .*/\1/'文件夹中)。我希望得到。

echo $WIDTH $HEIGHT $COLORS | awk '{ print <b>($1 * $2)/$3</b>;}'

正如您所看到的,结果总体上是好的。您可以使用15之类的数字作为分隔。

#!/bin/sh

cd images FILES=ls for FILE in $FILES; do IsIMAGE=identify $FILE 2>&1 | grep " no decode delegate " | grep -o "no" if [ "$IsIMAGE" = "no" ]; then continue; fi

IsIMAGE=`identify $FILE 2>&1 | grep " Improper image header " | grep -o "Improper"`
if [ "$IsIMAGE" = "Improper" ]; then continue; fi

echo `.././CheckCartoon.sh $FILE` $FILE

done

cd ..

是一幅画,但它看起来很逼真,所以很容易混淆。另外ls是我女朋友站在海边的照片,所以颜色的数量比往常少。毫不奇怪,为什么会出现混乱。

我在这里向你展示的仍然是一个原始理论。如果您真的想要一个确凿的指示,您可能需要找到多个指标并进行比较。例如,局部对比度。

希望这会有所帮助。

答案 1 :(得分:11)

理论上:

区分卡通和自然场景图像的一种方法是将给定图像与其“平滑”自我进行比较。这背后的动机是“平滑”的卡通图像在统计上将变化很大,而自然场景图像。换句话说,拍摄图像,漫画(即平滑)并减去原始结果

isNotACartoonIndex = mean( originalImage - smooth(originalImage) )

这种差异(即取其平均值)将给出平滑引起的变化水平。对于非光滑的原始(自然场景)图像,索引应该是高的,对于平滑的原始(卡通)图像,索引应该是低的。

SO问题already discusses how to cartoonify images

在实践中:

我建议使用 bilateral filtering 进行平滑/漫画: Original Filtered

可以使用cvSmooth function with the CV_BILATERAL parameter使用 OpenCV 进行双边过滤。

对于从原始图像中减去卡通图像,我会用HSV图像的Hue通道来做。这意味着您需要先将两个图像从RGB转换为HSV。

作为旁注,希望通过ImageMagick工作流实现这一目标可能会不必要地复杂化。

答案 2 :(得分:5)

作为第一遍,我会尝试计算图像颜色直方图的熵。类似卡通的图像应该具有较少的不同颜色的阴影,因此具有较低的熵。

这与NawaMan提出的类似,但这种方法更进了一步。像素数上的颜色数可能不足。例如,可能存在jpeg伪像,人为地增加图像中的颜色数量,但仅限于几个像素。在这种情况下,图像中的大多数像素仍然具有非常少的颜色,这将对应于低熵。

假设您从RGB图像开始。对于每个像素,R,G和B值的范围为0到255 您可以将此范围划分为n个区间,例如n可以是16个。您可以计算这些三维箱中的每一个都有多少像素。然后你需要将二进制值的值除以 总像素数,使您的直方图总和为1.然后计算熵,即熵 是 - sum_i p_i * log(p_i),其中p_i是第i个bin的值。

尝试使用不同的n值,并查看是否可以将真实图像与漫画分开。

答案 3 :(得分:0)

这是一个图像分类问题,AFAIK ImageMagick将能够做到。

对于如何使用训练数据训练“图像分类器”的一些想法,

opencv(处理计算机视觉)可能会有更多的帮助。