在爲一個項目訂購了半打網絡攝像頭之後,我注意到輸出上的顏色不一致。使用OpenCV進行網絡攝像頭色彩校準
爲了彌補這一點,我試圖採取模板圖像並提取R,G和B直方圖,並嘗試在此基礎上匹配目標圖像的RGB直方圖。
這從溶液中的描述激發了一個非常類似的問題Comparative color calibration
完美的解決方案將是這樣的:
爲了嘗試解決這個我寫的以下腳本表現不佳:
編輯(感謝@DanMašek和@ api55)
import numpy as np
def show_image(title, image, width = 300):
# resize the image to have a constant width, just to
# make displaying the images take up less screen real
# estate
r = width/float(image.shape[1])
dim = (width, int(image.shape[0] * r))
resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)
# show the resized image
cv2.imshow(title, resized)
def hist_match(source, template):
"""
Adjust the pixel values of a grayscale image such that its histogram
matches that of a target image
Arguments:
-----------
source: np.ndarray
Image to transform; the histogram is computed over the flattened
array
template: np.ndarray
Template image; can have different dimensions to source
Returns:
-----------
matched: np.ndarray
The transformed output image
"""
oldshape = source.shape
source = source.ravel()
template = template.ravel()
# get the set of unique pixel values and their corresponding indices and
# counts
s_values, bin_idx, s_counts = np.unique(source, return_inverse=True,
return_counts=True)
t_values, t_counts = np.unique(template, return_counts=True)
# take the cumsum of the counts and normalize by the number of pixels to
# get the empirical cumulative distribution functions for the source and
# template images (maps pixel value --> quantile)
s_quantiles = np.cumsum(s_counts).astype(np.float64)
s_quantiles /= s_quantiles[-1]
t_quantiles = np.cumsum(t_counts).astype(np.float64)
t_quantiles /= t_quantiles[-1]
# interpolate linearly to find the pixel values in the template image
# that correspond most closely to the quantiles in the source image
interp_t_values = np.interp(s_quantiles, t_quantiles, t_values)
return interp_t_values[bin_idx].reshape(oldshape)
from matplotlib import pyplot as plt
from scipy.misc import lena, ascent
import cv2
source = cv2.imread('/media/somadetect/Lexar/color_transfer_data/1/frame10.png')
s_b = source[:,:,0]
s_g = source[:,:,1]
s_r = source[:,:,2]
template = cv2.imread('/media/somadetect/Lexar/color_transfer_data/5/frame6.png')
t_b = source[:,:,0]
t_r = source[:,:,1]
t_g = source[:,:,2]
matched_b = hist_match(s_b, t_b)
matched_g = hist_match(s_g, t_g)
matched_r = hist_match(s_r, t_r)
y,x,c = source.shape
transfer = np.empty((y,x,c), dtype=np.uint8)
transfer[:,:,0] = matched_r
transfer[:,:,1] = matched_g
transfer[:,:,2] = matched_b
show_image("Template", template)
show_image("Target", source)
show_image("Transfer", transfer)
cv2.waitKey(0)
模板圖像:
目標圖像:
匹配圖像:
然後我發現阿德里安(pyimagesearch)試圖解決一個非常類似的問題在以下鏈接
結果似乎與一些飽和缺陷還算不錯。我歡迎任何有關如何解決此問題的建議或指示,以便可以校準所有網絡攝像頭輸出以基於一個模板圖像輸出相似的顏色。
雖然對機器視覺知之甚少,但這種顏色轉移方法對我來說似乎不太合適。這是一個完全不同的任務,它正在接近。在你的情況下,我想,你需要一些具有一些基礎模型的東西,這就解釋了爲什麼這些相機的行爲不同!忽視這種模式可能會導致太多的自由度/沒有足夠的正規化程度,從而導致不好的結果。再一次,沒有太多的經驗,但這些相機內部肯定沒有與RGB工作,但可能是一些拜耳模式,它允許更多的調整*噪聲模型*(傳感器數據可用?)。 – sascha
您是否訂購過一打不同品牌的相機,或者它們在同一品牌下有所不同? – Arturo