Thị giác máy tính với OpenCV-Python Bài 3, Phần 2: Phép toán số học trên hình ảnh

Thị giác máy tính với OpenCV-Python Bài 3, Phần 2: Phép toán số học trên hình ảnh

Thị giác máy tính với OpenCV-Python Bài 3, Phần 2: Phép toán số học trên hình ảnh

13:29 - 14/12/2021

Trong bài này chúng ta sẽ tìm hiểu một số phép toán số học trên hình ảnh như phép cộng, phép trừ, phép toán bit, ... thông qua các hàm cv2.add(), cv2.addWeighted(), ...

Thị giác máy tính với OpenCV-Python Bài 7 Phần 3: Nhận diện khuôn mặt
Thị giác máy tính với OpenCV-Python Bài 7 Phần 2: Phát hiện người đi bộ trong video
Thị giác máy tính với OpenCV-Python Bài 7 Phần 1: Phát hiện người đi bộ trong hình ảnh
Thị giác máy tính với OpenCV-Python Bài 6 Phần 2: Phép trừ nền
Thị giác máy tính với OpenCV-Python Bài 6 Phần 1: Bắt bám đối tượng với Meanshift và Camshift

Phép cộng hình ảnh

Chúng ta có thể ghép hai hình ảnh bằng hàm cv2.add() của OpenCV hoặc đơn giản bằng thao tác numpy: res = img1 + img2. Cả hai hình ảnh phải có cùng chiều sâu và loại, hoặc hình ảnh thứ hai phải là một giá trị vô hướng.

Ghi chú:

Có một sự khác biệt giữa phép cộng ảnh trong OpenCV và trong Numpy. Phép cộng ảnh trong OpenCV là một thao tác bão hòa trong khi phép cộng trong Numpy là một phép tính modul. Xem ví dụ dưới đây để rõ hơn:

  1. >>> x = np.uint8([250])
  2. >>> y = np.uint8([10])
  3. >>> print cv2.add(x,y)          // 250+10 = 260 => 255
  4. [[255]]       //Kết quả trả về tối đa là 255
  5. >>> print x+y # 250+10 = 260 % 256 = 4
  6. [4]           //Kết quả trả về được lấy theo modul của 256

Trong thực tế, hàm OpenCV sẽ cho ra một kết quả tốt hơn, do đó, tốt hơn hết nên nên sử dụng OpenCV.

Trộn hình ảnh

Đây cũng là phép cộng hình ảnh, nhưng các trọng số khác nhau được đưa ra cho hình ảnh để mang lại cảm giác hòa trộn hoặc trong suốt. Hình ảnh được thêm vào theo phương trình bên dưới:

g( x ) = (1 - α) f0(x) + α f1(x)

Bằng cách thay đổi α từ 0 → 1, chúng ta có thể thực hiện chuyển đổi từ hình ảnh này sang hình ảnh khác.

Lấy ví dụ trộn hai hình ảnh với trọng số lần lượt là 0,7 và 0,3. Hàm cv2.addWeighted() sẽ thực hiện theo phương trình sau trên hình ảnh:

dst = α ⋅ img1 + β⋅ img2 + γ

Trong đó, γ = 0. Xem đoạn code dưới đây để hiểu rõ hơn:

  1. import cv2
  2. import numpy as np
  3. img1 = cv2.imread('messi.jpg')
  4. img2 = cv2.imread('opencv.png')
  5. img1_resize = cv2.resize(img1, (300, 300))
  6. img2_resize = cv2.resize(img2, (300, 300))
  7. dst = cv2.addWeighted(img1_resize, 0.7, img2_resize, 0.3, 0)
  8. cv2.imshow('Image1 + Image2', dst)
  9. cv2.waitKey(0)
  10. cv2.destroyAllWindows()

Kết quả đoạn code trên:

 

 

Các phép toán Bitwise

Các phép toán bitwise bao gồm AND, OR, NOT và XOR. Chúng sẽ rất hữu ích khi trích xuất bất kỳ phần nào của hình ảnh, xác định và làm việc với ROI không phải hình chữ nhật, ... Dưới đây, chúng ta sẽ xem ví dụ về cách thay đổi một vùng cụ thể của hình ảnh.

Yêu cầu là đặt logo OpenCV phía trên một hình ảnh. Nếu cộng hai hình ảnh, kết quả sẽ thay đổi màu sắc. Nếu trộn hình ảnh, kết quả sẽ có được một hiệu ứng trong suốt. Nếu đó là một vùng hình chữ nhật, có thể sử dụng ROI như chúng ta đã làm trong phần trước. Nhưng logo OpenCV không phải là hình chữ nhật. Vì vậy, chúng ta có thể thực hiện bằng các thao tác bitwise như sau:

  1. # Load two images
  2. img1 = cv2.imread('messi.jpg')
  3. img2 = cv2.imread('opencv.png')
  4. # I want to put logo on top-left corner, So I create a ROI
  5. rows,cols,channels = img2.shape
  6. roi = img1[0:rows, 0:cols]
  7. # Now create a mask of logo and create its inverse mask also
  8. img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
  9. ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)
  10. mask_inv = cv2.bitwise_not(mask)
  11. # Now black-out the area of logo in ROI
  12. img1_bg = cv2.bitwise_and(roi, roi, mask = mask_inv)
  13. # Take only region of logo from logo image.
  14. img2_fg = cv2.bitwise_and(img2, img2, mask = mask)
  15. # Put logo in ROI and modify the main image
  16.  dst = cv2.add(img1_bg, img2_fg)
  17. img1[0:rows, 0:cols] = dst
  18. cv2.imshow('res', img1)
  19. cv2.waitKey(0)
  20. cv2.destroyAllWindows()

Kết quả sau khi chạy đoạn code trên:

 

 

Ở phần tiếp theo chúng ta sẽ tìm hiểu cách đánh giá và tối ưu hóa hiệu suất đoạn code trong OpenCV. 

 

 

(Sưu tầm)
VIỆN IMC
Tòa nhà IMC Tower, Số 176 Trường Chinh, Phường Khương
Thượng, Quận Đống Đa, Thành phố Hà Nội, Việt Nam
Tel/Fax : (+84) 24 3566 6232 / 24 3566 6234
Email: contact@imc.org.vn   Website: https://imc.org.vn