我正在嘗試開發一種根據顯示幕顏色更改 RGB LED 燈條的設備。為此,我計劃截取螢屏并標準化/取顯示幕中各個像素顏色的平均值。我在標準化影像和取出影像的平均顏色時遇到問題。這是我正在使用的代碼。
import numpy as np
import cv2
import mss
import time
def getAverageColor(frame):
(B, G, R) = 0, 0, 0
for i in frame:
for j in i:
B = j[0]
G = j[1]
R = j[2]
B /= len(frame) * len(frame[0])
G /= len(frame) * len(frame[0])
R /= len(frame) * len(frame[0])
return (B, G, R)
with mss.mss() as sct:
# Grab frames in an endless lopp until q key is pressed
time.sleep(2)
# Itterate the list of monitors, and grab one frame from each monitor (ignore index 0)
for monitor_number, mon in enumerate(sct.monitors[1:]):
monitor = {"top": mon["top"], "left": mon["left"], "width": mon["width"], "height": mon["height"], "mon": monitor_number} # Not used in the example
# Grab the data
img = np.array(sct.grab(mon)) # BGRA Image (the format BGRA, at leat in Wiqndows 10).
print(getAverageColor(img))
# Show down-scaled image for testing
# The window name is img0, img1... applying different monitors.
cv2.imshow(f'img{monitor_number}', cv2.resize(img, (img.shape[1]//4, img.shape[0]//4)))
key = cv2.waitKey(1)
if key == ord('q'):
break
cv2.destroyAllWindows()
該程式運行良好,但我想問一下是否有任何方法可以去除 openCV 本身的平均顏色,因為我的方法不是很好推薦,因為它的處理速度可能非常慢。不要添加這個,但代碼也不是很準確。
uj5u.com熱心網友回復:
在 Python 中使用串列和回圈進行影像處理for
效率低、速度慢且容易出錯。嘗試使用 Numpy 或矢量化庫,例如OpenCV、scikit-image、wand或PIL/Pillow。
制作一個從石灰綠到黃色的示例漸變影像影像,即沒有藍色、純綠色和紅色漸變,這將為我們提供簡單、易于檢查的方法:
magick -size 256x256 gradient:lime-yellow png24:start.png
現在使用 Numpy 獲取所有三個通道的方法:
import cv2
import numpy as np
# Load image
im = cv2.imread('start.png')
print(im.shape) # prints (256, 256, 3)
meanBlue = np.mean(im[...,0]) # gets value=0
meanGreen = np.mean(im[...,1]) # gets value=255.0
meanRed = np.mean(im[...,2]) # gets value=127.5
uj5u.com熱心網友回復:
我已經更新了函式 getAverageColor,想法是找到主色。我相信這會提供更好的顏色選擇。時間是個問題,我會更新以防萬一我能找到讓它更快的方法。
import pandas as pd
from scipy.cluster.vq import whiten
from scipy.cluster.vq import kmeans
# import matplotlib.pyplot as plt
def getAverageColor(frame):
r = []
g = []
b = []
print("Frames")
for row in frame:
for temp_r, temp_g, temp_b, temp in row:
r.append(temp_r)
g.append(temp_g)
b.append(temp_b)
df = pd.DataFrame({'r' : r, 'g' : g, 'b' : b})
df['scaled_r'] = whiten(df['r'])
df['scaled_b'] = whiten(df['b'])
df['scaled_g'] = whiten(df['g'])
cluster_centers, _ = kmeans(df[['scaled_r', 'scaled_b', 'scaled_g']], 3)
dominant_colors = []
r_std, g_std, b_std = df[['r', 'g', 'b']].std()
for cluster_center in cluster_centers:
red_scaled, green_scaled, blue_scaled = cluster_center
dominant_colors.append((red_scaled * r_std / 255, green_scaled * g_std / 255, blue_scaled * b_std / 255))
print("Dominant", dominant_colors)
return(dominant_colors[0])
# plt.imshow([dominant_colors])
# plt.show()
uj5u.com熱心網友回復:
我想用我想出的一個簡單的解決方案來回答這個問題。這可能不是這個問題的最佳解決方案,但它對我的用例來說足夠快了。如果有人可以改進我的解決方案,我將不勝感激。
def getAverageColor(frame):
r = []
g = []
b = []
print("Frames")
for row in frame:
for pixel in row:
r.append(pixel[0])
g.append(pixel[1])
b.append(pixel[2])
r_mean = np.mean(r)
g_mean = np.mean(g)
b_mean = np.mean(b)
return(r_mean, g_mean, b_mean)
這去掉了所有像素的平均值,并且不像之前定義的解決方案那樣只回傳一個平均顏色,在 90% 的情況下它只是一個棕色陰影。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/536327.html