+3

OpenCV With Python Part 5

Chào mừng các bạn đả quay lại với tutorial lần này. Trong bài hướng dẫn lần này, tôi sẽ giới thiệu một số thao tác số học đơn giản mà chúng ta có thể thực hiện trên các hình ảnh, cùng với việc giải thích những gì họ làm.

I. Giới thiệu.

Hình thái học toán học là một lý thuyết và kỹ thuật để phân tích và xử lý cấu trúc hình học, dựa trên lý thuyết tập hợp, lý thuyết lưới, cấu trúc liên kết và chức năng ngẫu nhiên. Hình thái học toán học phổ biến nhất được áp dụng cho hình ảnh kỹ thuật số. Ngoài ra hình thái học toán học nó có thể được sử dụng là tốt trên đồ thị, bề mặt mắt lưới, chất rắn, và nhiều các cấu trúc không gian khác.

Để làm điều này, chúng tôi sẽ yêu cầu hai hình ảnh có kích thước bằng nhau để bắt đầu, sau đó ta tiếp tục với một hình ảnh nhỏ và một hình ảnh lớn hơn.

II. Hình học và các Logic.

Để bắt đầu, tôi sẽ sử dụng 2 bức ảnh có kích thước như nhau nhé. Đầu tiên ta sẽ load bức ảnh1 .

import cv2
import numpy as np

# 500 x 250
img1 = cv2.imread('3D-Matplotlib.png')
add = img1

cv2.imshow('add',add)
cv2.waitKey(0)
cv2.destroyAllWindows()

Load bức ảnh thứ 2 củng tương tự nhé.

Sau đó ta tiến hành gộp 2 bức ảnh này theo source này nhé

import cv2
import numpy as np

# 500 x 250
img1 = cv2.imread('3D-Matplotlib.png')
img2 = cv2.imread('mainsvmimage.png')

add = img1+img2

cv2.imshow('add',add)
cv2.waitKey(0)
cv2.destroyAllWindows()

Kết quả : Sau khi gộp chúng laijbanj có cảm thấy khá lộn xộn không?

Bây giờ bạn muốn bỏ đi mới lộn xộn này. OpenCV có một phương pháp "add", chúng ta hãy xem những gì mà làm, thay thế cho "add" trước đó với:

import cv2
import numpy as np

# 500 x 250
img1 = cv2.imread('3D-Matplotlib.png')
img2 = cv2.imread('mainsvmimage.png')

# add = img1+img2
add = cv2.add(img1,img2)

cv2.imshow('add',add)
cv2.waitKey(0)
cv2.destroyAllWindows()

Kết quả :

Có lẽ đây không phải là kết quả lý tưởng nhất ở đây . Chúng ta có thể thấy rằng rất nhiều hình ảnh màu "trắng". Điều này là do màu sắc là 0-255, trong đó 255 là "ánh sáng đầy đủ." Ví dụ: (155,211,79) + (50, 170, 200) = 205, 381, 279 ... được dịch sang (205, 255,255).

Tiếp theo, chúng ta có thể thêm cho các hình ảnh trên với mỗi cái có một "weight" khác nhau như vậy để nói chuyện với nhau. Đây là cách có thể hoạt động và đưa ra kết quả khả quan hơn.

import cv2
import numpy as np

img1 = cv2.imread('3D-Matplotlib.png')
img2 = cv2.imread('mainsvmimage.png')

weighted = cv2.addWeighted(img1, 0.6, img2, 0.4, 0)
cv2.imshow('weighted',weighted)
cv2.waitKey(0)
cv2.destroyAllWindows()

Đối với phương pháp bổ sung này, ta có các thông số như sau : hình ảnh đầu tiên, trọng lượng, hình ảnh thứ hai, trọng lượng, và cuối cùng là gamma, là phép đo ánh sáng. Bây giờ chúng ta sẽ thực hiện điều đó.

Kết quả:

Đây là một số tùy chọn bổ sung, nhưng nếu bạn muốn dịch một hình ảnh sang một hình ảnh khác thì sao? Trong trường hợp này, bạn sẽ bắt đầu bằng hình ảnh lớn nhất, sau đó thêm (các) hình ảnh nhỏ hơn. Đối với điều này, chúng tôi sẽ sử dụng cùng một hình ảnh 3D-Matplotlib.png, nhưng sử dụng một hình mới, một biểu tượng Python chẳng hạn:

Bây giờ, chúng ta có thể lấy logo này, và đặt nó vào hình ảnh ban đầu. Điều đó sẽ khá dễ dàng (về cơ bản sử dụng cùng mã ish mà chúng ta đã sử dụng trong hướng dẫn trước đó, chúng ta đã thay thế Region of ROI bằng một hình mới), nhưng nếu chúng ta chỉ muốn phần logo, chứ không phải nền trắng ? Chúng ta có thể sử dụng nguyên tắc tương tự như chúng ta đã từng sử dụng trước đó để thay thế ROI, nhưng chúng ta cần một cách để "loại bỏ" nền của biểu tượng, sao cho màu trắng không ngăn chặn được hình ảnh nền. Đầu tiên tôi sẽ hiển thị mã đầy đủ, và sau đó giải thích chi tiết cho các bạn nhé :

import cv2
import numpy as np

# Load 2 bức ảnh nhé
img1 = cv2.imread('3D-Matplotlib.png')
img2 = cv2.imread('mainlogo.png')

#Tôi muốn đặt logo ở góc trên cùng bên trái, Vì vậy, tôi tạo ROI
rows,cols,channels = img2.shape
roi = img1[0:rows, 0:cols ]

# Bây giờ tạo ra một mặt nạ của logo và tạo mặt nạ nghịch đảo của nó
img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)

# thêm một ngưỡng
ret, mask = cv2.threshold(img2gray, 220, 255, cv2.THRESH_BINARY_INV)

mask_inv = cv2.bitwise_not(mask)

# Bây giờ hãy xoá hết diện tích logo trong ROI
img1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)

# Chỉ lấy vùng logo từ hình ảnh biểu tượng.
img2_fg = cv2.bitwise_and(img2,img2,mask = mask)

dst = cv2.add(img1_bg,img2_fg)
img1[0:rows, 0:cols ] = dst

cv2.imshow('res',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

Một số lượng phong nha đã xảy ra ở đây, và một vài điều mới xuất hiện. Điều đầu tiên chúng ta thấy đó là mới, là áp dụng một ngưỡng: ret, mask = cv2.threshold (img2gray, 220, 255, cv2.THRESH_BINARY_INV).

Chúng ta sẽ đề cập đến ngưỡng trong hướng dẫn tiếp theo, vì vậy hãy theo dõi các chi tiết cụ thể nhưng về cơ bản cách thức hoạt động là nó sẽ chuyển đổi tất cả các điểm ảnh thành màu đen hoặc trắng, dựa trên giá trị ngưỡng. Trong trường hợp của chúng tôi, ngưỡng là 220, nhưng chúng ta có thể sử dụng các giá trị khác, hoặc thậm chí tự động chọn một, đó là biến ret có thể được sử dụng cho. Tiếp theo, chúng ta thấy: mask_inv = cv2.bitwise_not (mặt nạ). Đây là một hoạt động bitwise. Về cơ bản, các toán tử này tương tự như các toán tử điển hình từ trăn, ngoại trừ một, nhưng chúng ta sẽ không chạm vào nó ở đây. Trong trường hợp này, phần vô hình là nơi có màu đen. Sau đó, chúng ta có thể nói rằng chúng ta muốn loại bỏ vùng này ra khỏi bức ảnh đầu tiên, và sau đó lấy image 2 và thay thế nội dung của nó trong khoảng trống đó.

Kết quả:

Trong hướng dẫn tiếp theo, chúng tôi thảo luận về ngưỡng ngưỡng sâu hơn.

III. Tài liệu tham khảo.

http://docs.opencv.org/ https://techmaster.vn/ https://pythonprogramming.net/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí