ImageMagick - 查找图像中三角形的平均颜色

ImageMagick - Find average color of a triangle in an image

这是 this question. From this image 的更高级版本,如何使用 ImageMagick/GraphicsMagick/a 不同的命令行工具从其坐标中获取三角形下方像素的平均颜色值?最好该解决方案也适用于其他多边形。

我会使用您的坐标通过 -draw 创建感兴趣区域的蒙版。然后可以使用它来将形状外部的区域转换为透明。然后像以前一样将图像缩小到 1x1 像素。

有点像@Bonzo 的回答的骨头,这是你可以做到的一种方法。

convert image.jpg                              \
   \( +clone -evaluate set 0 -fill white       \
      -draw "polygon 400,50 450,150 200,220"   \ 
      -write mask.png -transparent black       \
   \) -compose copyopacity -composite          \
   -write masked.png -resize 1x1!              \
   -alpha off -depth 8 -format "%[pixel:p{0,0}]\n" info:

srgb(145,114,94)

所以,也就是说... "load up your original image, and do the following stuff in parentheses on the side, away from the main image. Copy the image (-clone) and make it all black (-evaluate set 0), and make the fill colour white (-fill white) for the polygon we are about to draw. Draw the polygon (-draw "polygon ...") and save it in a file called mask.png. Now make all black areas of the image transparent. Good, we have a mask. Now go back to the original image by closing the parentheses. Copy the transparency from our mask image and apply it to our original image (-compose copyopacity -composite). Write the masked image out as masked.png. Resize to 1x1 pixel to average it. Now turn the transparency off and make that single pixel solid and write on the terminal what it is in human-readable terms."

您可以看到中间图像 - 这里是 mask.png:

这里是 masked.png:

是的,我知道它不完全匹配,但这只是因为您没有提供坐标,我不得不猜测它们!将您自己的数字放入 -draw polygon 部分,它将完全正常工作。

你实际上不需要任何中间图像,我只是为了调试和演示目的而保存它们,所以你可以从上面的命令中删除 -write mask.png-write masked.png

验证

为了检查四舍五入和平均的准确性,您可以用数学方法计算平均颜色。您使用与上述相同的基本技术,但通过计算蒙版中白色像素的比例来计算均值的比例因子,然后蒙版图像并查看蒙版中 R、G 和 B 的均值图像并按比例缩放它们...

convert -respect-parentheses image.jpg            \
   \( +clone -evaluate set 0 -fill white          \
     -draw "polygon 400,50 450,150 200,220"       \
     -format "Factor:%[fx:1/mean]\n" -write info: \
   \) -compose multiply -composite -verbose info: \
   | grep -E "Factor:|Red:|Green:|Blue:|mean:"

Factor:21.4019
Red:
  mean: 6.70078 (0.0262776)
Green:
  mean: 5.31762 (0.0208534)
Blue:
  mean: 4.40595 (0.0172782)

# Check the Red value - original method gave srgb(145,114,94)
echo "6.70078*21.4019"|bc
143.40942

# Check the Green value
echo "5.317*21.4019"|bc
113.7939

# Check the Blue value
echo "4.40595*21.4019"|bc
94.29570

顺便说一下,这个平均值是这样计算的:

convert -size 100x100 xc:"srgb(145,114,94)" average.png

我最终使用 scikit-image 和 numpy python 模块解决了我的问题。示例代码如下:

from skimage import io, draw
import numpy

# read in the image as a numpy array
image = io.imread("image.png")
# setup a list of coords in the polygon
polygon = numpy.array([[100, 100], [200, 100], [200, 200], [100, 200]])
# Get a 2D list of pixels in the polygon
pixels = image[draw.polygon(polygon[:, 1], polygon[:, 0])]
# Use the channels of each pixel to get averages and convert them to ints
channels = numpy.average(pixels, 0).astype(int)
# Print!
print(channels)