Hướng dẫn convert image color python - chuyển đổi màu sắc hình ảnh python

Tôi đang cố gắng sử dụng

lum_img = img[:,:,0]
9 để đọc trong hình ảnh RGB và chuyển đổi nó thành thang độ xám.

Trong Matlab, tôi sử dụng điều này:

img = rgb2gray(imread('image.png'));

Trong hướng dẫn matplotlib, họ không bao gồm nó. Họ chỉ đọc trong hình ảnh

import matplotlib.image as mpimg
img = mpimg.imread('image.png')

Và sau đó họ cắt mảng, nhưng đó không giống với việc chuyển đổi RGB thành thang độ xám từ những gì tôi hiểu.

lum_img = img[:,:,0]

Tôi thấy khó tin rằng Numpy hoặc Matplotlib không có chức năng tích hợp để chuyển đổi từ RGB sang màu xám. Đây không phải là một hoạt động phổ biến trong xử lý hình ảnh?

Tôi đã viết một chức năng rất đơn giản hoạt động với hình ảnh được nhập bằng

import numpy as np

def rgb2gray(rgb):

    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b

    return gray
0 trong 5 phút. Nó không hiệu quả khủng khiếp, nhưng đó là lý do tại sao tôi hy vọng một triển khai chuyên nghiệp tích hợp.

Sebastian đã cải thiện chức năng của tôi, nhưng tôi vẫn hy vọng tìm thấy một trong những tích hợp.

Thực hiện của Matlab (NTSC/PAL):

import numpy as np

def rgb2gray(rgb):

    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b

    return gray

Đối với Python, tôi chưa tìm thấy chức năng OpenCV cung cấp độ tương phản. Như những người khác đã đề xuất, có một số kỹ thuật để tự động tăng độ tương phản bằng cách sử dụng một công thức rất đơn giản.

Nội dung chính ShowShow

  • Tương phản
  • độ sáng và độ tương phản trong python và opencv
  • Một chút căn bản về ảnh kỹ thuật số (digital image)
  • Xử lý hình ảnh bằng Pillow và OpenCV
  • 1. Chuyển ảnh màu sang grayscale
  • 1.1 Code thủ công
  • 1.2 Sử dụng Pillow
  • 2. Thay đổi độ tương phản (contrast)
  • 3. Thay đổi độ sáng (brightness)
  • 4. Làm mờ (Gaussian blur)
  • 5. Làm tối 4 góc (vignette) sử dụng OpenCV và numpy
  • Phần này không liên quan tới xử lý hình ảnh ở trên
  • Tìm các cạnh bằng phương pháp Canny (Canny edge detection)
  • Vẽ countour của ảnh
  • Nhận diện gương mặt bằng OpenCV
  • Subscribe to Koodibar

Get the latest posts delivered right to your inbox

Đối với Python, tôi chưa tìm thấy chức năng OpenCV cung cấp độ tương phản. Như những người khác đã đề xuất, có một số kỹ thuật để tự động tăng độ tương phản bằng cách sử dụng một công thức rất đơn giản.

Nội dung chính Show

Tương phản

độ sáng và độ tương phản trong python và opencv

Một chút căn bản về ảnh kỹ thuật số (digital image)

Xử lý hình ảnh bằng Pillow và OpenCV

Tương phản

độ sáng và độ tương phản trong python và opencv

Một chút căn bản về ảnh kỹ thuật số (digital image)
new_image = f*(old_image - 127) + 127 = f*(old_image) + 127*(1-f)

Xử lý hình ảnh bằng Pillow và OpenCV

#pseudo code
if brightness > 0
    shadow = brightness
    highlight = 255
else:
    shadow = 0
    highlight = 255 + brightness
new_img = ((highlight - shadow)/255)*old_img + shadow

độ sáng và độ tương phản trong python và opencv

Một chút căn bản về ảnh kỹ thuật số (digital image)

import cv2
import numpy as np

# Open a typical 24 bit color image. For this kind of image there are
# 8 bits (0 to 255) per color channel
img = cv2.imread('mandrill.png')  # mandrill reference image from USC SIPI

s = 128
img = cv2.resize(img, (s,s), 0, 0, cv2.INTER_AREA)

def apply_brightness_contrast(input_img, brightness = 0, contrast = 0):
    
    if brightness != 0:
        if brightness > 0:
            shadow = brightness
            highlight = 255
        else:
            shadow = 0
            highlight = 255 + brightness
        alpha_b = (highlight - shadow)/255
        gamma_b = shadow
        
        buf = cv2.addWeighted(input_img, alpha_b, input_img, 0, gamma_b)
    else:
        buf = input_img.copy()
    
    if contrast != 0:
        f = 131*(contrast + 127)/(127*(131-contrast))
        alpha_c = f
        gamma_c = 127*(1-f)
        
        buf = cv2.addWeighted(buf, alpha_c, buf, 0, gamma_c)

    return buf


font = cv2.FONT_HERSHEY_SIMPLEX
fcolor = (0,0,0)

blist = [0, -127, 127,   0,  0, 64] # list of brightness values
clist = [0,    0,   0, -64, 64, 64] # list of contrast values


out = np.zeros((s*2, s*3, 3), dtype = np.uint8)

for i, b in enumerate(blist):
    c = clist[i]
    print('b, c:  ', b,', ',c)
    row = s*int(i/3)
    col = s*(i%3)
    
    print('row, col:   ', row, ', ', col)
    
    out[row:row+s, col:col+s] = apply_brightness_contrast(img, b, c)
    msg = 'b %d' % b
    cv2.putText(out,msg,(col,row+s-22), font, .7, fcolor,1,cv2.LINE_AA)
    msg = 'c %d' % c
    cv2.putText(out,msg,(col,row+s-4), font, .7, fcolor,1,cv2.LINE_AA)
    
    cv2.putText(out, 'OpenCV',(260,30), font, 1.0, fcolor,2,cv2.LINE_AA)

cv2.imwrite('out.png', out)

Xử lý hình ảnh bằng Pillow và OpenCV

Lưu ý: @utkarshbhardwaj đã đề xuất rằng người dùng Python 2.x phải chuyển mã tính toán hiệu chỉnh tương phản vào phao để nhận kết quả nổi, như vậy: @UtkarshBhardwaj has suggested that Python 2.x users must cast the contrast correction calculation code into float for getting floating result, like so: @UtkarshBhardwaj has suggested that Python 2.x users must cast the contrast correction calculation code into float for getting floating result, like so:

...
if contrast != 0:
        f = float(131*(contrast + 127))/(127*(131-contrast))
...
  • Một chút căn bản về ảnh kỹ thuật số (digital image)
  • Xử lý hình ảnh bằng Pillow và OpenCV
    • 1. Chuyển ảnh màu sang grayscale
      • 1.1 Code thủ công
      • 1.2 Sử dụng Pillow
    • 2. Thay đổi độ tương phản (contrast)
    • 3. Thay đổi độ sáng (brightness)
    • 4. Làm mờ (Gaussian blur)
    • 5. Làm tối 4 góc (vignette) sử dụng OpenCV và numpy
  • Cơm thêm
    • Tìm các cạnh bằng phương pháp Canny (Canny edge detection)
    • Vẽ countour của ảnh
    • Nhận diện gương mặt bằng OpenCV

Một chút căn bản về ảnh kỹ thuật số (digital image)

Một hình ảnh (kỹ thuật số) được tạo thành bởi nhiều phần tử gọi là pixel (hay điểm ảnh). Thường thì một hình được biểu diễn bằng một mảng hai chiều gồm nhiều pixels. Mỗi pixel (cụ thể là hình RGB) mang trong mình 3 thông số màu: Red, Green, Blue.Red, Green, Blue.Red, Green, Blue.

Ngoài ra, đối với không gian RGBA thì nó có một kênh thứ 4 là Alpha, trong đó Alpha là một thông số chỉ độ trong suốt của pixel đó.Alpha, trong đó Alpha là một thông số chỉ độ trong suốt của pixel đó.Alpha, trong đó Alpha là một thông số chỉ độ trong suốt của pixel đó.

Như đã nói ở trên, một pixel mang 3 giá trị màu, vì trên thực tế mỗi pixel được cấu thành bao gồm 3 sub-pixels. Và pixel cũng không có kích thước vật lý cụ thể, mà nó phụ thuộc vào pixel density. Mỗi pixel chứa được 256 (0-255) giá trị, cho nên về mặt lý thuyết 3 sub-pixels hiện thị được 256^3 = 16777216 (~16 triệu màu). Nhưng tất nhiên là mắt người chưa hẳn đã phân biệt được 16 triệu màu này.kích thước vật lý cụ thể, mà nó phụ thuộc vào pixel density. Mỗi pixel chứa được 256 (0-255) giá trị, cho nên về mặt lý thuyết 3 sub-pixels hiện thị được 256^3 = 16777216 (~16 triệu màu). Nhưng tất nhiên là mắt người chưa hẳn đã phân biệt được 16 triệu màu này.kích thước vật lý cụ thể, mà nó phụ thuộc vào pixel density. Mỗi pixel chứa được 256 (0-255) giá trị, cho nên về mặt lý thuyết 3 sub-pixels hiện thị được 256^3 = 16777216 (~16 triệu màu). Nhưng tất nhiên là mắt người chưa hẳn đã phân biệt được 16 triệu màu này.

Xử lý hình ảnh bằng Pillow và OpenCV

Trong toàn bài này mình sẽ sử dụng ảnh này làm ảnh gốc để chỉnh sửa. Phần code có hơi mì ăn liền cho nên bạn nào khó tính vui lòng bỏ qua.

1. Chuyển ảnh màu sang grayscale

Về cơ bản thì grayscale (hình trắng đen) là loại ảnh mà tất cả pixels chỉ mang thông tin về độ sáng, hay nói cách khác chỉ thể hiện các sắc thái của màu xám (Luminance mode). Trong không gian màu RGB, thì màu xám là màu mà các sắc tố Red, Green, Blue có giá trị bằng nhau. Ví dụ màu đỏ là

import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
6 thì nếu ta muốn chuyển nó sang xám thì lấy giá trị trung bình của 3 sub-pixels và tạo thành 1 pixel mới
import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
7Red, Green, Blue có giá trị bằng nhau. Ví dụ màu đỏ là
import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
6 thì nếu ta muốn chuyển nó sang xám thì lấy giá trị trung bình của 3 sub-pixels và tạo thành 1 pixel mới
import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
7Red, Green, Blue có giá trị bằng nhau. Ví dụ màu đỏ là
import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
6 thì nếu ta muốn chuyển nó sang xám thì lấy giá trị trung bình của 3 sub-pixels và tạo thành 1 pixel mới
import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
7

1.1 Code thủ công

1.2 Sử dụng Pillow

import matplotlib.image as mpimg
img = mpimg.imread('image.png')
4

2. Thay đổi độ tương phản (contrast)

3. Thay đổi độ sáng (brightness)

4. Làm mờ (Gaussian blur)

import matplotlib.image as mpimg
img = mpimg.imread('image.png')
5

5. Làm tối 4 góc (vignette) sử dụng OpenCV và numpy

Cơm thêm

Tìm các cạnh bằng phương pháp Canny (Canny edge detection)

Vẽ countour của ảnh

Nhận diện gương mặt bằng OpenCV

Một chút căn bản về ảnh kỹ thuật số (digital image)

Một hình ảnh (kỹ thuật số) được tạo thành bởi nhiều phần tử gọi là pixel (hay điểm ảnh). Thường thì một hình được biểu diễn bằng một mảng hai chiều gồm nhiều pixels. Mỗi pixel (cụ thể là hình RGB) mang trong mình 3 thông số màu: Red, Green, Blue.Red, Green, Blue.

Ngoài ra, đối với không gian RGBA thì nó có một kênh thứ 4 là Alpha, trong đó Alpha là một thông số chỉ độ trong suốt của pixel đó.Alpha, trong đó Alpha là một thông số chỉ độ trong suốt của pixel đó.

Như đã nói ở trên, một pixel mang 3 giá trị màu, vì trên thực tế mỗi pixel được cấu thành bao gồm 3 sub-pixels. Và pixel cũng không có kích thước vật lý cụ thể, mà nó phụ thuộc vào pixel density. Mỗi pixel chứa được 256 (0-255) giá trị, cho nên về mặt lý thuyết 3 sub-pixels hiện thị được 256^3 = 16777216 (~16 triệu màu). Nhưng tất nhiên là mắt người chưa hẳn đã phân biệt được 16 triệu màu này.kích thước vật lý cụ thể, mà nó phụ thuộc vào pixel density. Mỗi pixel chứa được 256 (0-255) giá trị, cho nên về mặt lý thuyết 3 sub-pixels hiện thị được 256^3 = 16777216 (~16 triệu màu). Nhưng tất nhiên là mắt người chưa hẳn đã phân biệt được 16 triệu màu này.

Xử lý hình ảnh bằng Pillow và OpenCV

Trong toàn bài này mình sẽ sử dụng ảnh này làm ảnh gốc để chỉnh sửa. Phần code có hơi mì ăn liền cho nên bạn nào khó tính vui lòng bỏ qua.

lum_img = img[:,:,0]
0

1. Chuyển ảnh màu sang grayscale

Về cơ bản thì grayscale (hình trắng đen) là loại ảnh mà tất cả pixels chỉ mang thông tin về độ sáng, hay nói cách khác chỉ thể hiện các sắc thái của màu xám (Luminance mode). Trong không gian màu RGB, thì màu xám là màu mà các sắc tố Red, Green, Blue có giá trị bằng nhau. Ví dụ màu đỏ là

4. Làm mờ (Gaussian blur)

Guassian blur Phương pháp làm mờ hình ảnh sử dụng Gussian function để giảm nhiễu và chi tiết trên bức ảnh.

Giải thích ngắn gọn thì cái ma trận 3x3 trong hình được gọi là

#pseudo code
if brightness > 0
    shadow = brightness
    highlight = 255
else:
    shadow = 0
    highlight = 255 + brightness
new_img = ((highlight - shadow)/255)*old_img + shadow
2. Chúng ta áp dụng cái filter như hình cho từng pixel thì cuối cùng chúng ta sẽ có một hình đã được làm mờ. Để sẽ giải thích chi tiết ở các bài sau.

*Nguồn Digital Image processing
import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
0

5. Làm tối 4 góc (vignette) sử dụng OpenCV và numpy

import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
1

Phần này không liên quan tới xử lý hình ảnh ở trên

Tìm các cạnh bằng phương pháp Canny (Canny edge detection)

import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
2

Vẽ countour của ảnh

Contour trong image proccesing là những đường nối những điểm liền nhau tạo thành hình dáng của vật trong ảnh (không phải contour trong trang điểm). Nó là một công cụ rất hữu ích trong nhận dạng và định danh các vật thể trong hình (object detection and recognition).

import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
3

Nhận diện gương mặt bằng OpenCV

Sử dụng Haar Cascade classifier của OpenCV. Tải về file haarcascade_frontalface_default.xml ở đây

import cv2
img = cv2.imread('input.png')
# call addWeighted function. use beta = 0 to effectively only operate one one image
out = cv2.addWeighted( img, contrast, img, 0, brightness)
output = cv2.addWeighted
4

Subscribe to Koodibar

Get the latest posts delivered right to your inbox