在OpenCV Python中将图像缩小为N种颜色 [英] reduce image to N colors in OpenCV Python

查看:216
本文介绍了在OpenCV Python中将图像缩小为N种颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只能在C/C ++中找到示例,而且它们似乎无法很好地映射到OpenCV API.我正在加载视频帧(既来自文件又来自网络摄像头),并希望将其缩小为16色,但映射到24位RGB色彩空间(这是我的输出所需要的-一个巨大的LED显示屏). /p>

我这样读取数据:

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

我确实找到了以下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()

这显然适用于OpenCV图像查看器,但是由于我需要RGB或RGBA格式,因此尝试在输出代码上执行相同的错误.我的输出是这样的:

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

每种颜色都表示为(r,g,b)元组.

关于如何进行这项工作的任何想法?

解决方案

我认为以下内容可能比kmeans更快,特别是在k = 16的情况下.

  1. 将彩色图像转换为灰色
  2. 对比度将该灰度图像拉伸为使得灰度图像介于0到255之间(将 normalize NORM_MINMAX 结合使用)
  3. 使用16作为箱数( calcHist )
  4. 计算此拉伸的灰度图像的直方图
  5. 现在您可以修改直方图的这16个值.例如,您可以对等级进行排序和分配(例如0到15),或者在0到255之间分配16个均匀分布的值(我认为这些值可以为您提供视频的一致输出)
  6. 将此直方图回投影到拉伸的灰度图像( calcBackProject )
  7. 将颜色映射表应用于此背投图像(您可能希望通过使用 applyColorMap 应用颜色映射表来缩放背投图像)

提示kmeans : 如果您将kmeans用于视频,则可以使用上一个框架中的聚类中心作为当前框架中kmeans的初始位置.这样,收敛所需的时间就更少了,因此后续帧中的kmeans很有可能会运行得更快.

I can only ever find examples in C/C++ and they never seem to map well to the 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).

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:

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. 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.

Any thoughts on how to make this work?

解决方案

I think the following could be faster than kmeans, specially with a k = 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)
  3. Calculate the histogram of this stretched gray image using 16 as the number of bins (calcHist)
  4. Now you can modify these 16 values of the histogram. 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)
  5. Backproject this histogram onto the stretched gray image (calcBackProject)
  6. Apply a color-map to this backprojected image (you might want to scale the backprojected image befor applying a colormap using 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. That way, it'll take less time to converge, so kmeans in the subsequent frames will most probably run faster.

这篇关于在OpenCV Python中将图像缩小为N种颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆