Python cv2 寻找图片中数量占比最高的像素
工作中遇到一个问题,即找出图片当中数量占比最高的像素值。
因时间紧迫,使用两层循环嵌套 naive 的完成了需求,效率非常慢,被人吐槽(可耻!)。
故开始寻找优化方法,发现利用 numpy 可以实现这个功能。
因此本文打算从最 naive 的方法开始,逐步比较不同方法,并试图探寻 numpy 执行如此迅速的原因。
以下是本篇章节,可以根据标题选择性观看。
naive 循环嵌套
1 载入图片;
2 遍历所有的pixel,统计每个像素值的个数;
3 然后寻找其中像素值最多的个数
这里主要耗时存在于 步骤2 中,对于所有pixel的遍历,即两次for循环的嵌套
512x512的图片,时间大概在 1.5s 左右
import cv2
import time
# load img
img = cv2.imread('./lena.jpg')
start_t = time.time()
pixel_num = {
}
(w,h,_) = img.shape
# search for each pixel and record the max times
max_value = None
max_times = 0
for i in range(w):
for j in range(h):
[b,g,r] = img[i,j]
pixel = (b,g,r)
if pixel in pixel_num.keys():
pixel_num[pixel] += 1
if pixel_num[pixel] > max_times:
max_times = pixel_num[pixel]
max_value = pixel
else:
pixel_num[pixel] = 1
end_t = time.time()
print(f'the most pixel is {max_value}, occupying {max_times/float(w*h):.6f}, time: {end_t-start_t:.6f}')
基于numpy的实现
本篇是基于np.ravel_multi_index() 和 np.bincount()
np.ravel_multi_index(),作用是把多维度数据映射到一维数据
np.bincount(),作用是统计一维数据中各个元素出现的次数
512x512的图片,时间大概在 0.25s 左右,比上面naive的方法(1.5s)快了83%
import cv2
import numpy as np
import time
# load img
img = cv2.imread('./lena.jpg')
start_t = time.time(