我有大量的JPEG缩略图,大小从120x90到320x240不等,我想把它们分类为真实生活或卡通式.
一个人怎么可能做到这一点使用的ImageMagick的工具:convert,compare,identify?或者还有其他程序可以解决这个问题吗?
Naw*_*Man 16
我猜你最好的位是直方图和像素数之间的无线电.卡通线图像的趋势是具有比现实生活更少的颜色数量.
您可以使用
COLORS=`convert picture.jpg -format %c histogram:info:- | wc -l`Run Code Online (Sandbox Code Playgroud)
计算图片有多少种颜色.并使用如下命令:
WIDTH=`jpeginfo picture.jpg | sed -r "s/.* ([0-9]+) x.*/\1/"`Run Code Online (Sandbox Code Playgroud)
和
HEIGHT=`jpeginfo picture.jpg | sed -r 's/.*x ([0-9]+) .*/\1/'`Run Code Online (Sandbox Code Playgroud)
提取宽度和高度.
然后使用此命令查找比率:
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
#!/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
Run Code Online (Sandbox Code Playgroud)
DONE
cd ..
现在测试你在这里复制文件.
图1:〜/ test/images/Cartoon-01.jpg
图2:〜/ test/images/Cartoon-02.png
图3:〜/ test/images/Cartoon-03.gif
http://dl.getdropbox.com/u/1961549/StackOverflow/SO1518347/Images.png
然后我跑./CheckAll.sh | sort(在test文件夹中).我希望得到.
00000000000003.31362 Real-03.jpg
00000000000004.61574 Real-02.jpg
00000000000009.89920 Cartoon-01.jpg
00000000000013.05870 Real-01.jpg
00000000000020.55470 Cartoon-03.gif
00000000000032.21900 Cartoon-02.png
Run Code Online (Sandbox Code Playgroud)
如您所见,结果通常很好.您可以使用15之类的数字作为分隔.
Cartoon-01.jpg是一幅画,但它看起来很逼真,所以很容易混淆.还有Real-01.jpg一张我女朋友站在海边的照片,所以颜色的数量比往常少.这并不奇怪为什么会发生混乱.
我在这里向你展示的仍然是一个原始的理论.如果您真的想要一个确凿的指示,您可能需要找到多个指标并进行比较.例如,局部对比度.
希望这会有所帮助.
Iva*_*van 11
区分卡通和自然场景图像的一种方法是将给定图像与其"平滑"自我进行比较.这背后的动机是"平滑"的卡通图像在统计上不会有太大变化,而自然场景图像则会变化很大.换句话说,拍摄图像,漫画(即平滑)并从原始图形中减去结果:
isNotACartoonIndex = mean( originalImage - smooth(originalImage) )
Run Code Online (Sandbox Code Playgroud)
这种差异(即取其平均值)将给出平滑引起的变化水平.对于非平滑的原始(自然场景)图像,索引应该是高的,对于平滑的原始(卡通)图像,索引应该是低的.
SO问题已经讨论了如何对图像进行漫画.
我建议用双边过滤进行平滑/漫画: 原文http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/luca.gif 过滤http://homepages.inf.ed.ac .UK/RBF/CVonline/LOCAL_COPIES/MANDUCHI1/luca_five.gif
使用带有CV_BILATERAL参数的cvSmooth函数可以使用OpenCV完成双边过滤.
至于从原始图像中减去卡通图像,我会用HSV图像的Hue通道来做.这意味着您需要先将两个图像从RGB转换为HSV.
作为旁注,希望通过ImageMagick工作流程实现这一点,可能会不必要地复杂化.
首先,我将尝试计算图像颜色直方图的熵。类似卡通的图像应减少不同颜色的阴影,从而降低熵。
这类似于NawaMan提出的方法,但此方法又向前迈了一步。颜色数量超过像素数量可能不够。例如,可能存在jpeg伪像,它们人为地增加了图像中的颜色数量,但仅适用于几个像素。在这种情况下,图像中的大多数像素仍将只有很少的颜色,这将对应于低熵。
假设您从RGB图像开始。对于每个像素,R,G和B值的范围是0到255。
您可以将此范围划分为n个bin,例如n可以是16。您将计算有多少像素落入这些3维bin中的每一个。然后,您需要将bin的值除以像素总数,以便直方图的总和为1。然后计算熵,即-sum_i p_i * log(p_i),其中p_i是像素的值。 ith bin。
尝试使用不同的n值,看看是否可以将真实图像与卡通图像分开。