Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 迭代图像并选择给定色调范围内的亮度/饱和度值,而不使用嵌套for循环_Python_List_Opencv - Fatal编程技术网

Python 迭代图像并选择给定色调范围内的亮度/饱和度值,而不使用嵌套for循环

Python 迭代图像并选择给定色调范围内的亮度/饱和度值,而不使用嵌套for循环,python,list,opencv,Python,List,Opencv,背后的故事: 我正在尝试构建一个简单的手部检测,它能够适应环境变化(主要是光线),因此每隔几分钟使用一个粗略估计手部位置的直方图(使用YOLO Darknet)重新校准一次。 这样做的目的是得到手指在末端的位置 目前我正在得到手的色调值,亮度和饱和度是固定的。 我为亮度和饱和度搜索编写了一个简短的嵌套for循环,它遍历色调范围中的所有元素,并找到其最大值和最小值,将其写入数组 现在我的问题是: 我知道python具有编写这种嵌套循环和列表修改/操作的功能—简短而优雅,我该怎么做 下面我有一个MW

背后的故事: 我正在尝试构建一个简单的手部检测,它能够适应环境变化(主要是光线),因此每隔几分钟使用一个粗略估计手部位置的直方图(使用YOLO Darknet)重新校准一次。 这样做的目的是得到手指在末端的位置

目前我正在得到手的色调值,亮度和饱和度是固定的。 我为亮度和饱和度搜索编写了一个简短的嵌套for循环,它遍历色调范围中的所有元素,并找到其最大值和最小值,将其写入数组

现在我的问题是: 我知道python具有编写这种嵌套循环和列表修改/操作的功能—简短而优雅,我该怎么做

下面我有一个MWE和一个示例图像

import numpy as np
import cv2

hue = 0
light = 1
satur = 2

img = cv2.imread('Untitled.png')
hls = cv2.cvtColor(img, cv2.COLOR_BGR2HLS)


# structure of histograms:
# 0, 2, 6 = histogram values for H, L and S
# 1, 3, 5 = bin values for H, L and S
histograms = [0] * 6

# Only 5 bins for a rough estimate of the skin color (so not too much is lost)
histograms[0], histograms[1] = np.histogram(hls[:, :, 0], 5)
histograms[2], histograms[3] = np.histogram(hls[:, :, 1], 5)
histograms[4], histograms[5] = np.histogram(hls[:, :, 2], 5)

# structure of HLS_bins:
# [Hue, Lightness, Saturation]         [min, min, min]
# [Hue, Lightness, Saturation]         [max, max, max]
HLS_bins = [[0, 200, 30], [0, 255, 255]]

# TODO alternative approach to the one below:
# todo...find the bin for the highest occuring color and select the Lightness
# todo...and Saturation according to the corresponding values

#  write in loop (elegant/generalized way) ?
# select the highest occurence of the hue
max_value_hue = max(histograms[0])
max_index_hue = list(histograms[0]).index(max_value_hue)
HLS_bins[0][0] = histograms[1][max_index_hue]
HLS_bins[1][0] = histograms[1][max_index_hue + 1]

min_value_light = 255
max_value_light = 0
min_value_saturation = 255
max_value_saturation = 0

for row in range(np.shape(hls)[0]):
    for col in range(np.shape(hls)[1]):
        if hls[row][col][hue] > HLS_bins[0][0] and hls[row][col][hue] < HLS_bins[1][0]:
            if hls[row][col][light] > max_value_light:
                max_value_light = hls[row][col][light]
            if hls[row][col][light] < min_value_light:
                min_value_light = hls[row][col][light]
            if hls[row][col][satur] > max_value_saturation:
                max_value_saturation = hls[row][col][satur]
            if hls[row][col][satur] < min_value_saturation:
                min_value_saturation = hls[row][col][satur]

HLS_bins[0][1] = min_value_light
HLS_bins[1][1] = max_value_light
HLS_bins[0][2] = min_value_saturation
HLS_bins[1][2] = max_value_saturation

HLS_bins = np.array(HLS_bins, dtype="uint8")
print(HLS_bins)
将numpy导入为np
进口cv2
色调=0
灯光=1
星期六=2
img=cv2.imread('Untitled.png')
hls=cv2.CVT颜色(img,cv2.COLOR\U BGR2HLS)
#直方图的结构:
#0,2,6=H、L和S的直方图值
#1,3,5=H、L和S的bin值
直方图=[0]*6
#只有5个箱子可以粗略估计肤色(因此不会损失太多)
直方图[0],直方图[1]=np.直方图(hls[:,:,0],5)
直方图[2],直方图[3]=np.直方图(hls[:,:,1],5)
直方图[4],直方图[5]=np.直方图(hls[:,:,2],5)
#HLS_料仓的结构:
#[色调、亮度、饱和度][min、min、min]
#[色调、亮度、饱和度][最大值、最大值、最大值]
HLS_bins=[[0,200,30],[0,255,255]]
#TODO替代方法如下所示:
#待办事项…找到最高颜色的箱子并选择亮度
#todo…和根据相应值的饱和度
#在循环中写入(优雅/通用的方式)?
#选择色调的最高出现频率
最大值\u色调=最大值(直方图[0])
max_index_hue=列表(直方图[0])。索引(max_值_hue)
HLS_bins[0][0]=直方图[1][max_index_hue]
HLS_bins[1][0]=直方图[1][max_index_hue+1]
最小值灯=255
最大值灯=0
最小值饱和度=255
最大值\u饱和度=0
对于范围内的行(np.形状(hls)[0]):
对于范围内的列(np.形状(hls)[1]):
如果hls[row][col][hue]>hls_箱[0][0]和hls[row][col][hue]max_值_light:
最大值灯=hls[行][列][灯]
如果hls[行][列][灯]最大值\U饱和度:
最大值饱和度=hls[行][列][饱和度]
如果hls[行][列][饱和]

大多数人应该已经猜到了,这是关于代码的这一部分:

for row in range(np.shape(hls)[0]):
        for col in range(np.shape(hls)[1]):
            if hls[row][col][hue] > HLS_bins[0][0] and hls[row][col][hue] < HLS_bins[1][0]:
                if hls[row][col][light] > max_value_light:
                    max_value_light = hls[row][col][light]
                if hls[row][col][light] < min_value_light:
                    min_value_light = hls[row][col][light]
                if hls[row][col][satur] > max_value_saturation:
                    max_value_saturation = hls[row][col][satur]
                if hls[row][col][satur] < min_value_saturation:
                    min_value_saturation = hls[row][col][satur]
用于范围内的行(np.形状(hls)[0]):
对于范围内的列(np.形状(hls)[1]):
如果hls[row][col][hue]>hls_箱[0][0]和hls[row][col][hue]max_值_light:
最大值灯=hls[行][列][灯]
如果hls[行][列][灯]最大值\U饱和度:
最大值饱和度=hls[行][列][饱和度]
如果hls[行][列][饱和]

那么,如何编写这篇优美的文章呢?

如果你想获得亮度和饱和度的最大值和最小值(最后两个通道),一种方法是直接在图像数组上使用
np.max()
np.min()
方法

要获得所需通道的此类值,可以从图像中对其进行切片,然后查询值:

import cv2
img = cv2.imread('Untitled.png')
hls = cv2.cvtColor(img, cv2.COLOR_BGR2HLS)

#reading Lightness channel: No. 1
#this slice basically means: "give me all rows and all cols from channel 1"
max_value_light = hls[:,:,1].max()
min_value_light = hls[:,:,1].min()

#reading Saturation channel: No. 2
# and this slice means: "give me all rows and all cols from channel 2"
max_value_saturation = hls[:,:,2].max()
min_value_saturation = hls[:,:,2].min()

编辑:根据您的说明,如果您想查询这样的最大/最小值,但只查询那些在特定时间间隔内的值
[hue\u min,hue\u max]
,您可以与max一起使用:

#obtain the min hue that falls within the interval
#hue is channel 0, so we slice for all x,y pixels and for that channel
theMin = hls[np.where((hls[:,:,0]>hue_min) & (hls[:,:,0]<hue_max))][:,0].min()
#same story with the rest, compare to your _min and _max and use it's index
#获取间隔内的最小色调
#色调是通道0,所以我们对所有x、y像素和该通道进行切片

theMin=hls[np.where((hls[:,:,0]>hue_min)和(hls[:,:,0]这实际上不是我的意思。我想得到最小/最大值,其中色调在范围hue_min和hue_max之间。你也能提供一种方法吗?@Spirit那么,假设你的最小值是10,最大值是50…你想要最大值(例如49)这正好介于两者之间,对吗?假设我理解正确,那不是我的意思。澄清:我根据图像直方图“定义”色调的最小值和最大值。然后我想在每个像素上“迭代”(而不是通过for循环)并检查:如果
hue_min@Spirit那么……您是否尝试过代码,看看这是否是您的意思?……无论如何,我看到您的评论澄清了问题,因此我将很快增强我的回答:)