如何找到最亮的像素?
How to find the brightest pixel?
如何找到图像中最亮像素的亮度(即 HSV 中的 V)?
我有大量图像将用作背景资产。为了确保没有亮点会分散观看者的注意力,我想找到所有最亮像素超过某个阈值的图像,以便对其进行返工。
是否有用于执行此操作的 Imagemagick 操作?
HSV colorspace在IM中称为HSB,所以可以这样得到image.jpg的直方图:
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.]*\)%.*//'
(这里取出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.]*\)%.*//')
(( $(echo "$Threshold < $Val" | bc) )) && echo "$pic: brightness exceeds threshold ($Val%)"
done
在你的图片目录中调用bash bChecker.sh 80
,这个脚本会显示所有亮度超过80%的图片。
最终答案
不确定我周末在想什么。您可以一步获得最大强度:
convert input.jpg -colorspace HSB -separate -delete 0,1 -format "%[max]" info:
输出值将在 运行ge 0-65535 范围内,因此如果您想知道是否有像素比 80% 更亮,您需要测试一个大于 80% 左右的值52,000。这假设您的量化是 16 位的,即当您执行 identify -version
.
时它说 Q16
更新答案
好的,现在回到电脑前。我认为我下面的第二个建议对您的用例有更多帮助。我被你问这个问题的方式误导了,让我相信你想找到最亮像素的 位置 ,而不是简单地知道它有多亮。无论如何...
让我们从这样的图像开始:
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&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"
我认为实际上我更喜欢直方图答案。如果您搜索单个最亮的像素,您很可能会被噪声误导。我认为采用直方图并找到(例如)第 95 个百分位数会更好,即。 95% 的像素比其暗的亮度。这对噪声不太敏感,并且可能对确定图像中的峰值亮度更有用。
我不太懂IM,不过vips有这方面的操作:
$ vips percent wtc.jpg 95
197
所以 95% 的像素比 197 更暗。当然,这是在 RGB space 中。我认为这对于这种情况可能已经足够好了。如果您真的想测试亮度,可以转换为 CIELAB 并测量 L*,但这需要在 Python/Ruby/whatever.
中编写一些脚本
如何找到图像中最亮像素的亮度(即 HSV 中的 V)?
我有大量图像将用作背景资产。为了确保没有亮点会分散观看者的注意力,我想找到所有最亮像素超过某个阈值的图像,以便对其进行返工。
是否有用于执行此操作的 Imagemagick 操作?
HSV colorspace在IM中称为HSB,所以可以这样得到image.jpg的直方图:
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.]*\)%.*//'
(这里取出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.]*\)%.*//')
(( $(echo "$Threshold < $Val" | bc) )) && echo "$pic: brightness exceeds threshold ($Val%)"
done
在你的图片目录中调用bash bChecker.sh 80
,这个脚本会显示所有亮度超过80%的图片。
最终答案
不确定我周末在想什么。您可以一步获得最大强度:
convert input.jpg -colorspace HSB -separate -delete 0,1 -format "%[max]" info:
输出值将在 运行ge 0-65535 范围内,因此如果您想知道是否有像素比 80% 更亮,您需要测试一个大于 80% 左右的值52,000。这假设您的量化是 16 位的,即当您执行 identify -version
.
Q16
更新答案
好的,现在回到电脑前。我认为我下面的第二个建议对您的用例有更多帮助。我被你问这个问题的方式误导了,让我相信你想找到最亮像素的 位置 ,而不是简单地知道它有多亮。无论如何...
让我们从这样的图像开始:
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&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"
我认为实际上我更喜欢直方图答案。如果您搜索单个最亮的像素,您很可能会被噪声误导。我认为采用直方图并找到(例如)第 95 个百分位数会更好,即。 95% 的像素比其暗的亮度。这对噪声不太敏感,并且可能对确定图像中的峰值亮度更有用。
我不太懂IM,不过vips有这方面的操作:
$ vips percent wtc.jpg 95
197
所以 95% 的像素比 197 更暗。当然,这是在 RGB space 中。我认为这对于这种情况可能已经足够好了。如果您真的想测试亮度,可以转换为 CIELAB 并测量 L*,但这需要在 Python/Ruby/whatever.
中编写一些脚本