Hướng dẫn average pixel value opencv python - giá trị pixel trung bình opencv python

Cách khắc phục lỗi

Có hai nguyên nhân tiềm năng cho lỗi này xảy ra:

  1. Tên tập tin là sai chính tả.
  2. Tệp hình ảnh không có trong thư mục làm việc hiện tại.

Để khắc phục sự cố này, bạn nên đảm bảo tên tệp được đánh vần chính xác (kiểm tra độ nhạy của trường hợp chỉ trong trường hợp) và tệp hình ảnh nằm trong thư mục làm việc hiện tại (có hai tùy chọn ở đây: bạn có thể thay đổi thư mục làm việc hiện tại trong IDE của bạn hoặc chỉ định đường dẫn đầy đủ của tệp).

Màu trung bình so với màu chi phối

Sau đó, để tính toán "màu trung bình" mà bạn phải quyết định ý của bạn là gì. Trong một hình ảnh thang độ xám, nó chỉ đơn giản là trung bình của các mức màu xám trên hình ảnh. Màu sắc thường được thể hiện thông qua các vectơ 3 chiều trong khi mức xám là vô hướng.

Màu trung bình là tổng của tất cả các pixel chia cho số lượng pixel. Tuy nhiên, cách tiếp cận này có thể mang lại một màu khác với màu thị giác nổi bật nhất. Những gì bạn thực sự có thể muốn là màu chi phối hơn là màu trung bình.dominant color rather than average colour.

Thực hiện

Hãy đi qua mã từ từ. Chúng tôi bắt đầu bằng cách nhập các mô -đun cần thiết và đọc hình ảnh:

import cv2
import numpy as np
from skimage import io

img = io.imread('https://sg.cdnki.com/huong-dan-average-pixel-value-opencv-python-gia-tri-pixel-trung-binh-opencv-python---aHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9ETk02NS5wbmc=.webp')[:, :, :-1]

Sau đó, chúng ta có thể tính toán giá trị trung bình của từng kênh màu theo phương thức tương tự với phương thức được đề xuất bởi @ruan b .:

average = img.mean(axis=0).mean(axis=0)

Tiếp theo, chúng tôi áp dụng phân cụm K-MEAN để tạo bảng màu với màu sắc đại diện nhất của hình ảnh (trong ví dụ đồ chơi này ____10 được đặt thành

average = img.mean(axis=0).mean(axis=0)
1).

pixels = np.float32(img.reshape(-1, 3))

n_colors = 5
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 200, .1)
flags = cv2.KMEANS_RANDOM_CENTERS

_, labels, palette = cv2.kmeans(pixels, n_colors, None, criteria, 10, flags)
_, counts = np.unique(labels, return_counts=True)

Và cuối cùng, màu chiếm ưu thế là màu bảng màu xảy ra thường xuyên nhất trên hình ảnh lượng tử hóa:

dominant = palette[np.argmax(counts)]

So sánh kết quả

Để minh họa sự khác biệt giữa cả hai phương pháp, tôi đã sử dụng hình ảnh mẫu sau:

Hướng dẫn average pixel value opencv python - giá trị pixel trung bình opencv python

Các giá trị thu được cho màu trung bình, tức là một màu có các thành phần là phương tiện của ba kênh màu sắc và màu sắc chi phối được tính toán thông qua phân cụm K-mean khá khác nhau:

In [30]: average
Out[30]: array([91.63179156, 69.30190754, 58.11971896])

In [31]: dominant
Out[31]: array([179.3999  ,  27.341282,   2.294441], dtype=float32)

Hãy xem những màu sắc đó trông như thế nào để hiểu rõ hơn về sự khác biệt giữa cả hai phương pháp. Ở phần bên trái của hình bên dưới, nó được hiển thị màu trung bình. Nó nổi lên rõ ràng rằng màu trung bình được tính toán không mô tả đúng nội dung màu của hình ảnh gốc. Trên thực tế, không có một pixel nào với màu đó trong hình ảnh gốc. Phần bên phải của hình cho thấy năm màu đại diện nhất được sắp xếp từ trên xuống dưới theo thứ tự quan trọng giảm dần (tần số xuất hiện). Bảng màu này cho thấy rõ rằng màu chiếm ưu thế là màu đỏ, phù hợp với thực tế là khu vực lớn nhất có màu đồng nhất trong hình ảnh gốc tương ứng với mảnh LEGO màu đỏ.

Hướng dẫn average pixel value opencv python - giá trị pixel trung bình opencv python

Đây là mã được sử dụng để tạo hình trên:

import matplotlib.pyplot as plt

avg_patch = np.ones(shape=img.shape, dtype=np.uint8)*np.uint8(average)

indices = np.argsort(counts)[::-1]   
freqs = np.cumsum(np.hstack([[0], counts[indices]/float(counts.sum())]))
rows = np.int_(img.shape[0]*freqs)

dom_patch = np.zeros(shape=img.shape, dtype=np.uint8)
for i in range(len(rows) - 1):
    dom_patch[rows[i]:rows[i + 1], :, :] += np.uint8(palette[indices[i]])
    
fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(12,6))
ax0.imshow(avg_patch)
ax0.set_title('Average color')
ax0.axis('off')
ax1.imshow(dom_patch)
ax1.set_title('Dominant colors')
ax1.axis('off')
plt.show(fig)

Tl; dr trả lời

Tóm lại, mặc dù tính toán màu trung bình - như được đề xuất trong câu trả lời của @ruan B. - là chính xác, kết quả mang lại có thể không thể hiện đầy đủ nội dung màu của hình ảnh. Một cách tiếp cận hợp lý hơn là việc xác định màu chiếm ưu thế thông qua lượng tử hóa vector (phân cụm).

  1. Sử dụng chức năng
    average = img.mean(axis=0).mean(axis=0)
    
    2 của Numpy để tìm màu trung bình của hình ảnh trong Python
  2. Sử dụng chức năng
    average = img.mean(axis=0).mean(axis=0)
    
    3 của
    average = img.mean(axis=0).mean(axis=0)
    
    4 để tìm các màu chiếm ưu thế trong hình ảnh trong Python

Hướng dẫn này sẽ thảo luận về việc tìm kiếm màu trung bình của hình ảnh bằng cách sử dụng hàm

average = img.mean(axis=0).mean(axis=0)
2 của Numpy trong Python.

Sử dụng chức năng average = img.mean(axis=0).mean(axis=0) 2 của Numpy để tìm màu trung bình của hình ảnh trong Python

Sử dụng chức năng

average = img.mean(axis=0).mean(axis=0)
3 của
average = img.mean(axis=0).mean(axis=0)
4 để tìm các màu chiếm ưu thế trong hình ảnh trong Python

Hướng dẫn này sẽ thảo luận về việc tìm kiếm màu trung bình của hình ảnh bằng cách sử dụng hàm

average = img.mean(axis=0).mean(axis=0)
2 của Numpy trong Python.

Trong toán học, chúng ta có thể tìm thấy trung bình của một vectơ bằng cách chia tổng của tất cả các phần tử trong vectơ cho tổng số phần tử. Một hình ảnh bao gồm các pixel và mỗi pixel có một màu cụ thể được xác định bởi giá trị bộ ba RGB.

Để tìm màu trung bình trong một hình ảnh, chúng ta phải lấy trung bình của tất cả các giá trị bộ ba RGB. Chúng ta có thể sử dụng chức năng

average = img.mean(axis=0).mean(axis=0)
7 để đọc hình ảnh và lưu trữ nó trong một ma trận.

Xem mã bên dưới.

import cv2
import numpy as np

src_img = cv2.imread('fruit.jpg')
average_color_row = np.average(src_img, axis=0)
average_color = np.average(average_color_row, axis=0)
print(average_color)

d_img = np.ones((312,312,3), dtype=np.uint8)
d_img[:,:] = average_color

cv2.imshow('Source image',src_img)
cv2.imshow('Average Color',d_img)
cv2.waitKey(0)

Output:

[ 66.37342135 132.52483748 176.58277285]

Hướng dẫn average pixel value opencv python - giá trị pixel trung bình opencv python

Chúng ta có thể sử dụng hàm

average = img.mean(axis=0).mean(axis=0)
2 của Numpy để tìm mức trung bình của ma trận hình ảnh và hiển thị nó bằng hàm
average = img.mean(axis=0).mean(axis=0)
9.

Chúng ta cũng có thể tạo một hình ảnh màu đen bằng cách sử dụng hàm

pixels = np.float32(img.reshape(-1, 3))

n_colors = 5
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 200, .1)
flags = cv2.KMEANS_RANDOM_CENTERS

_, labels, palette = cv2.kmeans(pixels, n_colors, None, criteria, 10, flags)
_, counts = np.unique(labels, return_counts=True)
0 của Numpy và sau đó đặt màu trung bình vào hình ảnh này và hiển thị nó bằng hàm
pixels = np.float32(img.reshape(-1, 3))

n_colors = 5
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 200, .1)
flags = cv2.KMEANS_RANDOM_CENTERS

_, labels, palette = cv2.kmeans(pixels, n_colors, None, criteria, 10, flags)
_, counts = np.unique(labels, return_counts=True)
1 của OpenCV.

Giá trị bộ ba RGB được lưu trong biến

pixels = np.float32(img.reshape(-1, 3))

n_colors = 5
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 200, .1)
flags = cv2.KMEANS_RANDOM_CENTERS

_, labels, palette = cv2.kmeans(pixels, n_colors, None, criteria, 10, flags)
_, counts = np.unique(labels, return_counts=True)
2 và nó cũng được hiển thị cùng với hình ảnh nguồn. Đối số đầu tiên trong hàm
average = img.mean(axis=0).mean(axis=0)
2 là hình ảnh nguồn.

Đối số thứ hai chỉ định hướng mà trung bình sẽ xảy ra. Trong mã trên,

pixels = np.float32(img.reshape(-1, 3))

n_colors = 5
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 200, .1)
flags = cv2.KMEANS_RANDOM_CENTERS

_, labels, palette = cv2.kmeans(pixels, n_colors, None, criteria, 10, flags)
_, counts = np.unique(labels, return_counts=True)
4 lấy các hàng trung bình trong ma trận hình ảnh.

Sử dụng chức năng average = img.mean(axis=0).mean(axis=0) 3 của average = img.mean(axis=0).mean(axis=0) 4 để tìm các màu chiếm ưu thế trong hình ảnh trong Python

Hướng dẫn này sẽ thảo luận về việc tìm kiếm màu trung bình của hình ảnh bằng cách sử dụng hàm

average = img.mean(axis=0).mean(axis=0)
2 của Numpy trong Python.

Trong toán học, chúng ta có thể tìm thấy trung bình của một vectơ bằng cách chia tổng của tất cả các phần tử trong vectơ cho tổng số phần tử. Một hình ảnh bao gồm các pixel và mỗi pixel có một màu cụ thể được xác định bởi giá trị bộ ba RGB.

Để tìm màu trung bình trong một hình ảnh, chúng ta phải lấy trung bình của tất cả các giá trị bộ ba RGB. Chúng ta có thể sử dụng chức năng

average = img.mean(axis=0).mean(axis=0)
7 để đọc hình ảnh và lưu trữ nó trong một ma trận.

Chúng ta có thể sử dụng hàm

average = img.mean(axis=0).mean(axis=0)
2 của Numpy để tìm mức trung bình của ma trận hình ảnh và hiển thị nó bằng hàm
average = img.mean(axis=0).mean(axis=0)
9.

Chúng ta có thể hiển thị các màu chiếm ưu thế bằng cách sử dụng chức năng

dominant = palette[np.argmax(counts)]
3 của OpenCV. Chúng tôi cũng sẽ hiển thị tỷ lệ phần trăm của các màu chiếm ưu thế.

Xem mã bên dưới.

import cv2, numpy as np
from sklearn.cluster import KMeans

def visualize_Dominant_colors(cluster, C_centroids):
    C_labels = np.arange(0, len(np.unique(cluster.labels_)) + 1)
    (C_hist, _) = np.histogram(cluster.labels_, bins = C_labels)
    C_hist = C_hist.astype("float")
    C_hist /= C_hist.sum()

    rect_color = np.zeros((50, 300, 3), dtype=np.uint8)
    img_colors = sorted([(percent, color) for (percent, color) in zip(C_hist, C_centroids)])
    start = 0
    for (percent, color) in img_colors:
        print(color, "{:0.2f}%".format(percent * 100))
        end = start + (percent * 300)
        cv2.rectangle(rect_color, (int(start), 0), (int(end), 50), \
                      color.astype("uint8").tolist(), -1)
        start = end
    return rect_color

# Load image
src_image = cv2.imread('fruit.jpg')
src_image = cv2.cvtColor(src_image, cv2.COLOR_BGR2RGB)
reshape_img = src_image.reshape((src_image.shape[0] * src_image.shape[1], 3))

# Display dominant colors Present in the image
KM_cluster = KMeans(n_clusters=5).fit(reshape_img)
visualize_color = visualize_Dominant_colors(KM_cluster, KM_cluster.cluster_centers_)
visualize_color = cv2.cvtColor(visualize_color, cv2.COLOR_RGB2BGR)
cv2.imshow('visualize_Color', visualize_color)
cv2.waitKey()

Output:

[250.02183207 247.76400891 234.31283544] 10.79%
[229.50988728 214.10649735 107.32981816] 17.88%
[191.01593309  56.83353011  24.6890951 ] 22.11%
[75.10083377 57.61393153 30.72486672] 24.38%
[193.66472128 165.29669679  36.39122105] 24.84%

Hướng dẫn average pixel value opencv python - giá trị pixel trung bình opencv python

Như được hiển thị, giá trị bộ ba RGB cùng với tỷ lệ phần trăm màu sắc chi phối được hiển thị trong đầu ra. OpenCV đọc hình ảnh trong không gian màu BRG rằng lý do tại sao chúng tôi chuyển đổi hình ảnh thành RGB bằng hàm

dominant = palette[np.argmax(counts)]
4 của OpenCV.

Hàm

dominant = palette[np.argmax(counts)]
5 trong mã trên được sử dụng để tạo hình ảnh trống và sau đó chúng tôi đã sử dụng hàm
dominant = palette[np.argmax(counts)]
3 để tạo hình chữ nhật có màu trội theo tỷ lệ phần trăm của chúng trên đầu hình ảnh trống.

Giá trị của số lượng cụm được đặt thành 5 trong mã trên, nhưng chúng ta có thể sử dụng bao nhiêu cụm tùy thích.

Nếu chúng ta sử dụng 10 cụm, mã sẽ trả về các màu chiếm ưu thế, nhưng mã sẽ mất nhiều thời gian hơn 5 cụm. Chúng tôi cũng có thể đặt nhiều đối số khác trong hàm

average = img.mean(axis=0).mean(axis=0)
3, như các lần lặp tối đa bằng cách sử dụng đối số
dominant = palette[np.argmax(counts)]
8 được đặt thành 300 theo mặc định.

Chúng tôi cũng có thể đặt dung sai bằng đối số

dominant = palette[np.argmax(counts)]
9 được đặt thành 0,0001 theo mặc định và thuật toán được sử dụng để tìm các cụm được đặt thành tự động theo mặc định. Kiểm tra liên kết này để biết thêm chi tiết về chức năng
average = img.mean(axis=0).mean(axis=0)
3.

Đối số đầu tiên của hàm

dominant = palette[np.argmax(counts)]
3 là hình ảnh mà chúng tôi muốn vẽ hộp màu. Đối số thứ hai là vị trí bắt đầu, sẽ đặt điểm bắt đầu hình chữ nhật.

Đối số thứ ba là vị trí kết thúc của hình chữ nhật. Đối số thứ tư xác định màu hình chữ nhật ở định dạng bộ ba BGR và đối số thứ năm là độ dày đường của hình chữ nhật.

Nếu độ dày đường được đặt thành -1, hình chữ nhật sẽ được lấp đầy bằng màu.