image-processing - 如何自动确定图像文件描绘的是照片还是 'graphic'?

标签 image-processing imagemagick photo graphic

如何自动确定图像文件描绘的是照片还是“图形”?

例如使用 Imagemagick?

最佳答案

我的知识有限,但我阅读了一篇论文并找到了一种使用 ImageMagick 计算图像熵的方法 - 一些聪明的人可能会喜欢检查它!

#!/bin/bash
image=$1
# Get number of pixels in image
px=$(convert -format "%w*%h\n" "$image" info:|bc)
# Calculate entropy 
# See this paper www1.idc.ac.il/toky/imageProc-10/Lectures/04_histogram_10.ppt
convert "$image" -colorspace gray -depth 8 -format "%c" histogram:info:- | \
   awk -F: -v px=$px '{p=$1/px;e+=-p*log(p)} END {print e}'

因此,您可以将上面的脚本保存为 entropy,然后执行以下一次以使其可执行:

chmod +x entropy

然后你可以像这样使用它:

entropy image.jpg

它似乎确实为真实照片产生了更大的数字,为计算机图形产生了更低的数字。

另一个想法是查看 channel 间相关性。通常,在数码照片上,不同波长的光相互之间有很强的相关性,所以如果红色分量增加,绿色分量就会增加,蓝色分量也会增加,但如果红色分量减少,绿色和蓝色分量都会增加也减少。如果将其与计算机图形进行比较,人们倾向于使用大而粗的原色来绘制图形,因此大红色条形图或饼图图形在 channel 之间根本不相关。我拍了一张风景的数码照片并将其调整为 1 像素宽和 64 像素高,我在下面使用 ImageMagick 显示它 - 你会看到红色下降的地方绿色和蓝色也会下降......

convert DSC01447.JPG -resize 1x64! -depth 8 txt:

0,0: (168,199,235)  #A8C7EB  srgb(168,199,235)
0,1: (171,201,236)  #ABC9EC  srgb(171,201,236)
0,2: (174,202,236)  #AECAEC  srgb(174,202,236)
0,3: (176,204,236)  #B0CCEC  srgb(176,204,236)
0,4: (179,205,237)  #B3CDED  srgb(179,205,237)
0,5: (181,207,236)  #B5CFEC  srgb(181,207,236)
0,6: (183,208,236)  #B7D0EC  srgb(183,208,236)
0,7: (186,210,236)  #BAD2EC  srgb(186,210,236)
0,8: (188,211,235)  #BCD3EB  srgb(188,211,235)
0,9: (190,212,236)  #BED4EC  srgb(190,212,236)
0,10: (192,213,234)  #C0D5EA  srgb(192,213,234)
0,11: (192,211,227)  #C0D3E3  srgb(192,211,227)
0,12: (191,208,221)  #BFD0DD  srgb(191,208,221)
0,13: (190,206,216)  #BECED8  srgb(190,206,216)
0,14: (193,207,217)  #C1CFD9  srgb(193,207,217)
0,15: (181,194,199)  #B5C2C7  srgb(181,194,199)
0,16: (158,167,167)  #9EA7A7  srgb(158,167,167)
0,17: (141,149,143)  #8D958F  srgb(141,149,143)
0,18: (108,111,98)  #6C6F62  srgb(108,111,98)
0,19: (89,89,74)  #59594A  srgb(89,89,74)
0,20: (77,76,61)  #4D4C3D  srgb(77,76,61)
0,21: (67,64,49)  #434031  srgb(67,64,49)
0,22: (57,56,43)  #39382B  srgb(57,56,43)
0,23: (40,40,34)  #282822  srgb(40,40,34)
0,24: (39,38,35)  #272623  srgb(39,38,35)
0,25: (38,37,37)  #262525  srgb(38,37,37)
0,26: (40,39,38)  #282726  srgb(40,39,38)
0,27: (78,78,57)  #4E4E39  srgb(78,78,57)
0,28: (123,117,90)  #7B755A  srgb(123,117,90)
0,29: (170,156,125)  #AA9C7D  srgb(170,156,125)
0,30: (168,154,116)  #A89A74  srgb(168,154,116)
0,31: (153,146,96)  #999260  srgb(153,146,96)
0,32: (156,148,101)  #9C9465  srgb(156,148,101)
0,33: (152,141,98)  #988D62  srgb(152,141,98)
0,34: (151,139,99)  #978B63  srgb(151,139,99)
0,35: (150,139,101)  #968B65  srgb(150,139,101)
0,36: (146,135,98)  #928762  srgb(146,135,98)
0,37: (145,136,97)  #918861  srgb(145,136,97)
0,38: (143,133,94)  #8F855E  srgb(143,133,94)
0,39: (140,133,92)  #8C855C  srgb(140,133,92)
0,40: (137,133,92)  #89855C  srgb(137,133,92)
0,41: (136,133,91)  #88855B  srgb(136,133,91)
0,42: (131,124,81)  #837C51  srgb(131,124,81)
0,43: (130,121,78)  #82794E  srgb(130,121,78)
0,44: (134,123,78)  #867B4E  srgb(134,123,78)
0,45: (135,127,78)  #877F4E  srgb(135,127,78)
0,46: (135,129,79)  #87814F  srgb(135,129,79)
0,47: (129,125,77)  #817D4D  srgb(129,125,77)
0,48: (106,105,65)  #6A6941  srgb(106,105,65)
0,49: (97,99,60)  #61633C  srgb(97,99,60)
0,50: (120,121,69)  #787945  srgb(120,121,69)
0,51: (111,111,63)  #6F6F3F  srgb(111,111,63)
0,52: (95,98,55)  #5F6237  srgb(95,98,55)
0,53: (110,111,63)  #6E6F3F  srgb(110,111,63)
0,54: (102,105,60)  #66693C  srgb(102,105,60)
0,55: (118,120,66)  #767842  srgb(118,120,66)
0,56: (124,124,68)  #7C7C44  srgb(124,124,68)
0,57: (118,120,65)  #767841  srgb(118,120,65)
0,58: (114,116,64)  #727440  srgb(114,116,64)
0,59: (113,114,63)  #71723F  srgb(113,114,63)
0,60: (116,117,64)  #747540  srgb(116,117,64)
0,61: (118,118,65)  #767641  srgb(118,118,65)
0,62: (118,117,65)  #767541  srgb(118,117,65)
0,63: (114,114,62)  #72723E  srgb(114,114,62)

从统计上讲,这是协方差。我倾向于使用照片的红色和绿色 channel 来评估这一点——因为在拜耳网格中,每个红色和蓝色站点都有两个绿色站点,因此绿色 channel 在两个站点之间取平均值,因此最不容易受到影响噪音。蓝色最容易受到噪音的影响。所以测量协方差的代码可以这样写:

#!/bin/bash
# Calculate Red Green covariance of image supplied as parameter
image=$1
convert "$image" -depth 8 txt: | awk ' \
    {split($2,a,",")
     sub(/\(/,"",a[1]);R[NR]=a[1];
     G[NR]=a[2];
     # sub(/\)/,"",a[3]);B[NR]=a[3]
    }
    END{
      # Calculate mean of R,G and B
      for(i=1;i<=NR;i++){
         Rmean=Rmean+R[i]
         Gmean=Gmean+G[i]
         #Bmean=Bmean+B[i]
      }
      Rmean=Rmean/NR
      Gmean=Gmean/NR
      #Bmean=Bmean/NR
      # Calculate Green-Red and Green-Blue covariance
      for(i=1;i<=NR;i++){
          GRcov+=(G[i]-Gmean)*(R[i]-Rmean)
          #GBcov+=(G[i]-Gmean)*(B[i]-Bmean)
      }
      GRcov=GRcov/NR
      #GBcov=GBcov/NR
      print "Green Red covariance: ",GRcov
      #print "GBcovariance: ",GBcov
    }'

我做了一些测试,效果也很好——但是具有大的白色或黑色背景的图形似乎也有很好的相关性,因为白色和黑色(以及所有灰色调区域)上的红色=绿色=蓝色,所以你需要要小心他们。然而,这导致了另一个想法,照片几乎从来没有纯白色或黑色(除非曝光真的很差),而图形确实有白色背景,所以您可以使用的另一个测试是计算纯黑色和白色像素的数量,如下所示:

convert photo.jpg -colorspace gray -depth 8 -format %c histogram:info:-| egrep "\(0\)|\(255\)"
     2: (  0,  0,  0) #000000 gray(0)
   537: (255,255,255) #FFFFFF gray(255)

这个有 2 个黑色和 537 个纯白色像素。

我想你现在可能已经足够进行体面的启发式了!

根据我的评论,您可以使用这些 ImageMagick 命令:

# Get EXIF information
identify -format "%[EXIF*]" image.jpg

# Get number of colours
convert image.jpg -format "%k" info:

其他响应者可能会建议其他参数,您可以使用以下方法找到大部分参数:

identify -verbose image.jpg

关于image-processing - 如何自动确定图像文件描绘的是照片还是 'graphic'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26807303/

相关文章:

python - 寻找物体中心: showing wrong coordinate outside of the target object

image - 双线性图像插值/缩放 - 计算示例

php - 我无法使用 ImageMagick 进行转换

ImageMagick:如何将多个 TIFF 文件批量合并为一个目录中的单个 TIFF 文件?

java - 是否可以使用 java 创建像 Instagram 这样的照片滤镜程序?

math - 寻找透视图像的角度

c++ - 如何为 OpenCV 找到对象的正确 HSV 阈值?

linux - 图像魔法 : takes too much time at linux server

ios - "Saved photo"在用户允许照片库权限之前弹出警报?

ios - 如何确保通过我的 iOS 应用程序上传的照片不模糊?