【发布时间】:2016-01-21 21:02:52
【问题描述】:
这是this question 的更高级版本。从this image,如何使用 ImageMagick/GraphicsMagick/其他命令行工具从其坐标中获取三角形下像素的平均颜色值?最好该解决方案也适用于其他多边形。
【问题讨论】:
标签: colors imagemagick average graphicsmagick
这是this question 的更高级版本。从this image,如何使用 ImageMagick/GraphicsMagick/其他命令行工具从其坐标中获取三角形下像素的平均颜色值?最好该解决方案也适用于其他多边形。
【问题讨论】:
标签: colors imagemagick average graphicsmagick
我会使用您的坐标来使用 -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)
也就是说... “加载您的原始图像,并在远离主图像的一侧的括号中执行以下操作。复制图像(-clone)并使其全黑(-evaluate set 0),并将我们要绘制的多边形的填充颜色设为白色 (-fill white)。绘制多边形 (-draw "polygon ...") 并将其保存在名为 mask.png 的文件中。现在将所有黑色区域图像透明。好的,我们有一个蒙版。现在通过关闭括号返回原始图像。从我们的蒙版图像中复制透明度并将其应用于我们的原始图像(-compose copyopacity -composite)。将蒙版图像写成masked.png。调整大小为 1x1 像素以对其进行平均。现在关闭透明度,使单个像素成为实心,然后在终端上以人类可读的方式写下它的内容。"
你可以看到中间图像 - 这里是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)
【讨论】: