简体   繁体   English

在OpenCV Python中将图像缩小为N种颜色

[英]reduce image to N colors in OpenCV Python

I can only ever find examples in C/C++ and they never seem to map well to the OpenCV API. 我只能在C / C ++中找到示例,而且它们似乎从未很好地映射到OpenCV API。 I'm loading video frames (both from files and from a webcam) and want to reduce them to 16 color, but mapped to a 24-bit RGB color-space (this is what my output requires - a giant LED display). 我正在加载视频帧(既来自文件又来自网络摄像头),并希望将它们缩小为16色,但映射到24位RGB色彩空间(这是我的输出所需要的-一个巨大的LED显示屏)。

I read the data like this: 我这样读取数据:

ret, frame = self._vid.read() 
image = cv2.cvtColor(frame, cv2.COLOR_RGB2BGRA)

I did find the below python example, but cannot figure out how to map that to the type of output data I need: 我确实找到了以下python示例,但无法弄清楚如何将其映射到所需的输出数据类型:

import numpy as np
import cv2

img = cv2.imread('home.jpg')
Z = img.reshape((-1,3))

# convert to np.float32
Z = np.float32(Z)

# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 8
ret,label,center=cv2.kmeans(Z,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)

# Now convert back into uint8, and make original image
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))

cv2.imshow('res2',res2)
cv2.waitKey(0)
cv2.destroyAllWindows()

That obviously works for the OpenCV image viewer but trying to do the same errors on my output code since I need an RGB or RGBA format. 这显然适用于OpenCV图像查看器,但由于我需要RGB或RGBA格式,因此尝试在输出代码上执行相同的错误。 My output works like this: 我的输出如下所示:

for y in range(self.height):
    for x in range(self.width):
        self._led.set(x,y,tuple(image[y,x][0:3]))

Each color is represented as an (r,g,b) tuple. 每种颜色都表示为(r,g,b)元组。

Any thoughts on how to make this work? 对如何进行这项工作有任何想法吗?

I think the following could be faster than kmeans, specially with ak = 16. 我认为以下内容可能比kmeans更快,尤其是ak = 16时。

  1. Convert the color image to gray 将彩色图像转换为灰色
  2. Contrast stretch this gray image to so that resulting image gray levels are between 0 and 255 (use normalize with NORM_MINMAX ) 对比度将此灰度图像拉伸到,以使所得的图像灰度级在0到255之间(使用NORM_MINMAX进行 归一化
  3. Calculate the histogram of this stretched gray image using 16 as the number of bins ( calcHist ) 使用16作为箱数( calcHist )计算此拉伸的灰度图像的直方图
  4. Now you can modify these 16 values of the histogram. 现在,您可以修改直方图的这16个值。 For example you can sort and assign ranks (say 0 to 15), or assign 16 uniformly distributed values between 0 and 255 (I think these could give you a consistent output for a video) 例如,您可以对等级进行排序和分配(例如0到15),或者在0到255之间分配16个均匀分布的值(我认为这些可以为您提供视频的一致输出)
  5. Backproject this histogram onto the stretched gray image ( calcBackProject ) 将此直方图反投影到拉伸的灰度图像上( calcBackProject
  6. Apply a color-map to this backprojected image (you might want to scale the backprojected image befor applying a colormap using applyColorMap ) 将颜色图应用于此背投图像(您可能要缩放背投图像,以便使用applyColorMap应用颜色

Tip for kmeans : If you are using kmeans for video, you can use the cluster centers from the previous frame as the initial positions in kmeans for the current frame. kmeans提示 :如果将kmeans用于视频,则可以将上一帧的聚类中心用作当前帧在kmeans中的初始位置。 That way, it'll take less time to converge, so kmeans in the subsequent frames will most probably run faster. 这样一来,收敛所需的时间就会减少,因此后续帧中的kmeans很可能会运行得更快。

You can speed up your processing by applying the k-means on a downscaled version of your image. 通过将k均值应用于图像的缩小版本,可以加快处理速度。 This will give you the cluster centroids. 这将为您提供群集质心。 You can then quantify each pixel of the original image by picking the closest centroid. 然后,您可以通过选择最接近的质心来量化原始图像的每个像素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM