2012-02-22 8 views
14

Tôi vừa cố vẽ biểu đồ bằng giao diện Python OpenCV mới (cv2).Vẽ biểu đồ trong OpenCV-Python

Dưới đây là đoạn code tôi đã cố gắng:

import cv2 
import numpy as np 
import time 

img = cv2.imread('zzz.jpg') 
h = np.zeros((300,256,3)) 
b,g,r = cv2.split(img) 
bins = np.arange(256).reshape(256,1) 
color = [ (255,0,0),(0,255,0),(0,0,255) ] 

for item,col in zip([b,g,r],color): 
    hist_item = cv2.calcHist([item],[0],None,[256],[0,255]) 
    cv2.normalize(hist_item,hist_item,0,255,cv2.NORM_MINMAX) 
    hist=np.int32(np.around(hist_item)) 
    pts = np.column_stack((bins,hist)) 
    cv2.polylines(h,[pts],False,col) 

h=np.flipud(h) 

cv2.imshow('colorhist',h) 
cv2.waitKey(0) 

Và nó hoạt động tốt. Dưới đây là biểu đồ kết quả tôi thu được.

enter image description here


Sau đó tôi sửa đổi mã một chút.

tức là thay đổi dòng thứ sáu trong mã b,g,r = cv2.split(img) thành b,g,r = img[:,:,0], img[:,:,1], img[:,:,2] (vì nó hoạt động nhanh hơn một chút so với cv2.split).

Bây giờ đầu ra là một cái gì đó khác nhau. Dưới đây là đầu ra.

enter image description here


Tôi đã kiểm tra các giá trị của b,g,r từ cả các mã. Họ giống nhau.

Sự khác biệt nằm ở đầu ra của cv2.calcHist. Kết quả của hist_item là khác nhau trong cả hai trường hợp.

Câu hỏi:

Làm thế nào để nó xảy ra? Tại sao kết quả của cv2.calcHist khác nhau khi đầu vào giống nhau?

EDIT

Tôi đã thử một đoạn mã khác nhau. Bây giờ, một phiên bản khó hiểu của mã đầu tiên của tôi.

import cv2 
import numpy as np 

img = cv2.imread('zzz.jpg') 
h = np.zeros((300,256,3)) 
b,g,r = img[:,:,0],img[:,:,1],img[:,:,2] 
bins = np.arange(257) 
bin = bins[0:-1] 
color = [ (255,0,0),(0,255,0),(0,0,255) ] 

for item,col in zip([b,g,r],color): 
    N,bins = np.histogram(item,bins) 
    v=N.max() 
    N = np.int32(np.around((N*255)/v)) 
    N=N.reshape(256,1) 
    pts = np.column_stack((bin,N)) 
    cv2.polylines(h,[pts],False,col,2) 

h=np.flipud(h) 

cv2.imshow('img',h) 
cv2.waitKey(0) 

Và đầu ra giống với giá trị đầu tiên.

enter image description here

Bạn có thể lấy hình ảnh ban đầu của tôi ở đây: zzz.jpg

Cảm ơn bạn.

Trả lời

11

Bạn nên sao chép các mảng:

b,g,r = img[:,:,0].copy(), img[:,:,1].copy(), img[:,:,2].copy() 

Nhưng, kể từ calcHist() có thể chấp nhận tham số kênh, bạn không cần phải chia img của bạn để ba mảng.

import cv2 
import numpy as np 

img = cv2.imread('zzzyj.jpg') 
h = np.zeros((300,256,3)) 

bins = np.arange(256).reshape(256,1) 
color = [ (255,0,0),(0,255,0),(0,0,255) ] 

for ch, col in enumerate(color): 
    hist_item = cv2.calcHist([img],[ch],None,[256],[0,255]) 
    cv2.normalize(hist_item,hist_item,0,255,cv2.NORM_MINMAX) 
    hist=np.int32(np.around(hist_item)) 
    pts = np.column_stack((bins,hist)) 
    cv2.polylines(h,[pts],False,col) 

h=np.flipud(h) 

cv2.imshow('colorhist',h) 
cv2.waitKey(0) 
+0

Cần 'sao chép' là gì? Và những gì có nghĩa là calcHist() chấp nhận tham số kênh? Nó thực sự biểu thị điều gì? –

+1

bạn có thể gọi 'cv2.calcHist ([img], [CH], None, [256], [0,255])' để tính toán biểu đồ kênh CH của img, tức là img [:,:, CH]. Bạn cần phải sao chép mảng vì dữ liệu trong img [:,:, 0] không liên tục. – HYRY

+0

bạn có nghĩa là c_contiguous? Ý nghĩa của nó là gì? –