1. 程式人生 > 程式設計 >python下對hsv顏色空間進行量化操作

python下對hsv顏色空間進行量化操作

更新:優化了程式碼,理由numpy的ufunc函式功能替換了之前的雙重for迴圈,測試圖片大小為692*1024*3,優化前執行時間為6.9s,優化後為0.8s。

由於工作需要,需要計算顏色直方圖來提取顏色特徵,但若不將顏色空間進行量化,則直方圖向量維數過高,不便於使用。但是看了opencv API後並未發現提供了相關函式能夠在計算顏色直方圖的同時進行量化,因此這部分功能只能自己實現。下面分為兩個部分進行介紹:

一、顏色空間量化表

由於RGB模型不夠直觀,不符合人類視覺習慣,因此在進行顏色特徵提取前,需要將照片從RGB顏色模型轉換為更符合人類視覺的HSV模型。在提取顏色特徵時,最常用的方法之一為顏色直方圖法,但一張圖片中出現的顏色一般特別多,導致直方圖向量的維數較高,因此需要對HSV空間進行量化。根據人眼對顏色的感知特性,採用較為常用的量化方法,即按照如下對應關係進行量化:

python下對hsv顏色空間進行量化操作

基於上述量化表,將各顏色分量按照下述公式合成為72維一維向量:python下對hsv顏色空間進行量化操作

二、量化程式碼

程式碼使用純python寫成,效率偏低,處理388*500畫素的照片用時1.45秒。在quantilize函式中,未使用if-else判斷語句,因此至少節省了1/3的時間。但這個速度顯然是無法令人滿意的,用C++效率應該會更高點。如果有人有更好的想法,歡迎在下方評論交流。

#-*-coding:utf-8-*-
import cv2
import numpy as np
from datetime import datetime
from matplotlib import pyplot as plt

def colors(imagepath):
  img = cv2.imread(imagepath)
  hsv = cv2.cvtColor(img,cv2.COLOR_RGB2HSV)
  nhsv = np.zeros(hsv.shape[:2],dtype=np.uint8)
  t2 = datetime.now()
  for i in range(hsv.shape[0]):
    for j in range(hsv.shape[1]):
      nhsv[i][j] = quantilize(hsv[i][j])
  print datetime.now() - t2
  hist = cv2.calcHist([nhsv],[0],None,[72],[0,71]) # 40x faster than np.histogramfaster than np.histogram
  plt.plot(hist,color = 'r')
  plt.xlim([0,72])
  plt.show()

def quantilize(value):
  '''hsv直方圖量化
  value : [21,144,23] h,s,v
  opencv中,h-[0,180],s-[0,255],v-[0,255]
  '''
  # 
  value[0] = value[0] * 2
  hlist = [20,40,75,155,190,270,290,316,360]
  svlist = [21,178,255]
  for i in range(len(hlist)):
    if value[0] <= hlist[i]:
      h = i % 8
      break
  for i in range(len(svlist)):
    if value[1] <= svlist[i]:
      s = i
      break
  for i in range(len(svlist)):
    if value[2] <= svlist[i]:
      v = i
      break
  return 9 * h + 3 * s + v

以上,歡迎批評交流~

三、更新

#-*-coding:utf-8-*-
import cv2
import numpy as np
from datetime import datetime
from matplotlib import pyplot as plt

hlist = [20,360]
svlist = [21,255]

def quantilize(h,v):
  '''hsv直方圖量化'''
  # value : [21,v
  h = h * 2
  for i in range(len(hlist)):
    if h <= hlist[i]:
      h = i % 8
      break
  for i in range(len(svlist)):
    if s <= svlist[i]:
      s = i
      break
  for i in range(len(svlist)):
    if v <= svlist[i]:
      v = i
      break
  return 9 * h + 3 * s + v

quantilize_ufunc = np.frompyfunc(quantilize,3,1) # 自定義ufunc函式,即將quantilize函式轉化為ufunc函式,其輸入引數為3個,輸出引數為1個。

def colors(img):
  hsv = cv2.cvtColor(img,cv2.COLOR_RGB2HSV)
  nhsv = quantilize_ufunc(hsv[:,:,0],hsv[:,1],2]).astype(np.uint8) # 由於frompyfunc函式返回結果為物件,所以需要轉換型別
  hist = cv2.calcHist([nhsv],71]) # 40x faster than np.histogram
  hist = hist.reshape(1,hist.shape[0]).astype(np.int32).tolist()[0]
  return hist

if __name__ == '__main__':
  img_path = path + 'test.jpg'
  img = cv2.imread(img_path)
  colors(img)

結果

[0,11,31490,100,32685,28,313,3268,31,558364,6,1,441,2301,92,34056,396,2682,84,5,712,137,55,1215,20,2,224,13838,56,23474,63,23,4764,2335,25,27,2302,1676,59,389]

以上這篇python下對hsv顏色空間進行量化操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。