如何找到图像中最亮像素的亮度(即HSV中的V)?
我有大量的图像用作背景资源。为了确保没有可能分散观众注意力的亮点,我想找到所有最亮像素超过一定阈值的图像,以便重新加工。
执行此操作是否有Imagemagick操作?
答案 0 :(得分:3)
convert image.jpg -colorspace HSB -format %c histogram:info:-
您需要根据第三列(=亮度)对输出进行反向排序,然后选择第一行,这样可以实现(对于以下内容,我假设Linux为OS):
convert image.jpg -colorspace HSB -format %c histogram:info:- \
| sort -t',' -gr -k 3 | head -1
下一步是过滤亮度值本身。让我们使用sed
并注意alpha通道:
sed 's/.* hsb.*,.*,\([0-9.]*\)%.*/\1/'
(这取hsb-或hsba-括号中的第三个数字,即最亮像素亮度的百分比值。)
综合所有这些,我们可以像这样编写一个小脚本bChecker.sh
来检查png和jpg文件:
#/bin/bash
Threshold=${1-75}
echo checking threshold $Threshold%
find . -name "*.png" -o -name "*.jpg" | while read pic; do
Val=$(convert "$pic" -colorspace HSB -format %c histogram:info:- | \
sort -t',' -gr -k 3 | head -1 | \
sed 's/.* hsb.*,.*,\([0-9.]*\)%.*/\1/')
(( $(echo "$Threshold < $Val" | bc) )) && echo "$pic: brightness exceeds threshold ($Val%)"
done
在图像为bash bChecker.sh 80
的目录中调用,此脚本显示亮度超过80%的所有图像。
答案 1 :(得分:1)
最终答案
不确定周末我在想什么。您只需一步即可获得这样的最大强度:
convert input.jpg -colorspace HSB -separate -delete 0,1 -format "%[max]" info:
输出值将在0-65535范围内,因此,如果您想知道是否有比80%更亮的像素,则需要测试大于52,000的值。这假定您的量化是16位,即当您执行Q16
时它会显示identify -version
。
更新了答案
好的,现在回到电脑前。我认为我的第二个建议对你的用例有更多的里程数。我被你问这个问题的方式误导了你想要找到最亮像素的位置,而不是简单地知道它是多么明亮。总之...
让我们从这样的图像开始:
convert -size 500x100 gradient:black-"rgb(204,204,204)" input.jpg
从黑色到80%白色 - 即204/255 = 80%
如果我们现在转换为HSB和阈值为70%,我们得到这个(我在它周围放了一个人工红色边框,这样你就可以看到白色区域的范围):
如果我再次这样做并且阈值为75%,那么你得到:
如果我将阈值设置为80%:
如果我看一下像这样的70%,75%和80%图像的平均像素:
convert input.jpg -colorspace HSB -separate -delete 0,1 -threshold 70% -format "%[mean]" info:
8519.55
convert input.jpg -colorspace HSB -separate -delete 0,1 -threshold 75% -format "%[mean]" info:
4587.45
convert input.jpg -colorspace HSB -separate -delete 0,1 -threshold 80% -format "%[mean]" info:
0
当没有像素超过80%的亮度阈值时,您可以看到平均值变为零 - 希望这正是您想要的。
上一个答案
我测试了它,并且我意识到我已经省略了-verbose
标志来获取统计信息输出,所以如果你像这样运行它,它应该可以做到这一点:
convert image.jpg -colorspace HSL -separate -delete 0,1 -threshold 80% -verbose info: | grep -i "max"
它实际上做了什么?它将图像转换为HSL颜色空间,然后将三个通道分开 - 色调,饱和度和亮度。然后删除H&amp; S频道,只留下亮度。然后,它将亮度低于80%的所有像素设置为零(全黑),将所有超过80%的像素设置为一个(全白色)。然后它会查看亮度通道中的最大像素,如果所有像素都低于80%阈值,则最大像素将为0.如果任何像素超出80%阈值,则最大像素将为1。
原始答案
我远远没有一台机器上面有ImageMagick来检查,但我相信我现在运行以下命令来找到最小像素,我猜它可以改编:
identify -precision 5 -define identify:locate=minimum -define identify:limit=3 image.jpg
文档为here。
另一种选择是转换为HSB色彩空间,分离通道并丢弃色调和饱和度,只留下亮度。现在是阈值,比如80%,以便低于阈值的所有内容都变为零(黑色),80%以上的所有内容都变为白色。现在检查平均或最大像素,如果它不为零,则有超过阈值的值。未经测试,因为我仍然远离计算机:
convert image.jpg -colorspace HSB -separate -delete 0,1 -threshold 80% info: | grep -Ei "mean|max"
答案 2 :(得分:0)
我认为我实际上更喜欢直方图答案。如果搜索单个最亮的像素,则可能会被噪声误导。我认为最好采用直方图并找到(例如)第95百分位数,即。 95%的像素比黑暗的亮度。这对噪声的敏感性要小得多,可能对确定图像的峰值亮度更有用。
我不太了解IM,但是vips有一个操作:
$ vips percent wtc.jpg 95
197
所以95%的像素比197更暗。当然,这是RGB空间中的。我认为这对于这种情况可能已经足够了。如果你真的想要测试亮度,你可以转换为CIELAB并测量L *,但这需要在Python / Ruby /中使用一些脚本。