Bài tập về loc trung bình không gian năm 2024

RFẪG 8. IÈI OỖ CểI @FÞGM MKHG

- Yụ nỬgm Ehtcho, faẽi Rytfag Ęỉ tfỸi fkọg ièi oâk taèg nƲỐk Ęïy.- Iƨ số nỡ ckọu ẩgf nawgcahn tỠ ckg` nƲỐk Ęïy4 fp4//www.kehmlprailsskgmpchil.iae/raatQjclsQZ9/kehmlQnhthohsls.ftec

Oâk 84

Oớ cễi trugm oãgf

- Gfấp ẩgf xèe K Ęậu vâa gfƲ fãgf 8.8Fãgf 8.8 ắgf mỘi- Cễi ẩgf K oẸgm oớ cễi trugm oãgf vỐk ièi `åif tfƲỐi < x <0 = x =, 89 x 89- Fkỉg tfỀ `ằt quẩ4 ắgf mỘi vâ ẩgf shu `fk cễi trugm oãgf.- ^Ỡ `ằt quẩ gfấg ĘƲứi, féy gfấg xët Ʋu Ękỉe vâ gfƲứi Ękỉe iửh oớ cễi trugmoãgf.

Oâk ?4

Oớ cễi trugm vỀ

- Gfấp ẩgf xèe K Ęậu vâa gfƲ Fãgf 8.8- ^fäe gfkỌu euỘk äu vâa ẩgf K ĘƲứi ẩgf K8.- Cễi ẩgf K8 oẸgm oớ cễi trugm vỀ.- Fkỉg tfỀ `ằt quẩ4 ắgf mỘi K vâ ẩgf K8. Gfấg xët `ằt quẩ

Oâk 9

4 Oớ cễi ehx vâ oớ cễi ekg

Bài tập về loc trung bình không gian năm 2024

- Gfấp ẩgf xèe K Ęậu vâa- Cễi ẩgf xèe K oẸgm oớ cễi ehx vâ oớ cễi ekg `åif tfƲỐi < x <.- Fkỉg tfỀ ẩgf mỘi vâ ẩgf shu `fk cễi.- NỸh vâa `ằt quẩ féy gfấg xët `ằt quẩ vâ cõ mkẩk.

Rfèt fkọg okäg sụ nỬgm ĘẨa fâe

Oâk >

4

Ièi oớ cễi pfèt fkọg okäg nỸh träg ĘẨa fâe oấi 8

.

- Gfấp ẩgf xèe K Ęậu vâa.- Cễi ẩgf xèe K oẸgm ièi oớ cễi Yaolc, Rrlwk vâ Ihggy.- Fkỉg tfỀ `ằt quẩ mộe ẩgf mỘi vâ ẩgf shu `fk cễi.- NỸh vâa `ằt quẩ féy gfấg xët vỈ ièi oớ cễi.- Gfấg xët vỈ ièi fọ sỘ iửh oớ cễi pfèt fkọg okäg.

Oâk <4

Ièi oớ cễi pfèt fkọg okäg nỸh träg ĘẨa fâe oấi ?

- Gfấp ẩgf xèe K Ęậu vâa.- Cễi ẩgf xèe K oẸgm ièi oớ cễi Chpchikhg vâ CaM.- Fkỉg tfỀ `ằt quẩ mộe ẩgf mỘi vâ ièi ẩgf shu `fk cễi.- Gfấg xët vỈ ièi `ằt quẩ gfấg ĘƲứi.

IÈI IÏ\ FệK OỞ Y\GM4

8. NỸh träg ièi fkỉu okằt vỈ oớ cễi trugm vỀ, féy mkẩk tfåif tẨk sha oớ cễi trugm oãgf`fþgm tfỉ caẨk oề gfkỌu euỘk äu.?. Oớ cễi ehx fhy oớ cễi ekg iù tfỉ sụ nỬgm Ęỉ caẨk oề gfkỌu euỘk äu `fþgm19. Rfậg träg Ęé tfẩa cuấg vỈ eớt sỘ oớ cễi `fþgm mkhg. Féy trãgf oây tfäe fhk oớcễi gỡh vâ tfẩa cuấg vỈ ièi tfuới gf iửh gù.

RFẪG ?. ^ďGM IơồGM ắGF

- Okằg ĘỜk ïe oẩg ĘƲứi sụ nỬgm Ęỉ ifuyỉg ĘỜk gmƲứi iƲổgm Ęớ pkxlc tragm ẩgf.

- Okằg ĘỜk fâe eū câe ifa oừi ẩgf sègm fƨg vỐk mheeh 3 8 vâ tỘk fƨg vỐkmheeh 78.- Okằg ĘỜk fâe cam câe ifa oừi ẩgf sègm fƨg tragm `fk okằg ĘỜk cam gmƲứi câe ifaẩgf tỘk Ęk.- Iïg oẸgm cƲứi Ęộ xèe ĘƲứi sụ nỬgm Ęỉ tĉgm iƲổgm Ęớ tƲƨgm pfẩg tragm ẩgf.^ragm pfëp okằg ĘỜk gây, eớt nẩk fẻp iẬi mkè trỀ iƲổgm Ęớ sẵ ĘƲứi ègf xẨ tfâgfeớt nẩk rớgm ièi mkè trỀ iƲổgm Ęớ.- @ëa nég Ęớ tƲƨgm pfẩg ĘƲứi sụ nỬgm Ęỉ tĉgm nẩk ièi mkè trỀ pkxlc oẸgm ièif tfhyĘỜk tỽ cọ ièi mkè trỀ pkxlc tragm ẩgf Ęậu vâa.

Oâk :

4

Féy Ęễi ẩgf Ęậu vâa gfƲ fãgf ?.8, tfỸi fkọg ièi pfëp okằg ĘỜk ïe oẩg,okằg ĘỜk fâe eū vâ fâe cam. Fkỉg tfỀ `ằt quẩ Ęậu rh Ęỉ ekgf ifừgm ifa ièi `ằtcuấg ố Ęïy.Fãgf ?.8. ắgf mỘi

RFẪG 9. OKặG ĒỞK JA\_KL_ ZÂ IÈI OỖ CểI EKỂG ^ẪG YỒ9.8 Okằg ĘỜk Jaurklr

- ^ragm pfậg cễi `fþgm mkhg, pfëp cễi `fþgm mkhg tƲƨgm ừgm vỐk if ifấp4f(t) 5 P * mU(t) - Gằu mễk okằg ĘỜk Jaurklr iửh fâe gây câ F tfã th iù4 F 5 J.M

Bài tập về loc trung bình không gian năm 2024

Lọc ảnh (làm mịn ảnh, làm mượt ảnh) là một bước rất quan trọng trong xử lý ảnh. Lọc ảnh thực tế có rất nhiều tác dụng như loại bỏ nhiễu, tìm biên đối tượng. Bài viết này sẽ giới thiệu nguyên tắc chung của lọc ảnh và một số phép lọc ảnh cơ bản.

A. Nguyên tắc chung của lọc ảnh

Nguyên tắc chung của các phương pháp lọc là cho ma trận ảnh nhân với một ma trận lọc (Kernel). Ma trận lọc lọc (Kernel) còn có thể được gọi là cửa số chập (trong phép nhân chập), cửa sổ lọc, mặt nạ,… Trong bài viết này tôi sử dụng thuật ngữ ma trận lọc (Kernel).

Việc nhân ảnh với ma trận lọc giống như việc trượt ma trận lọc theo hàng trên ảnh và nhân với từng vùng của ảnh, cộng các kết quả lại tạo thành kết quả của điểm ảnh trung tâm.

Minh họa việc nhân ma trận ảnh. Hình ảnh được lấy từ https://github.com/vdumoulin/conv_arithmetic

Ma trận đầu vào I được nhân với ma trận lọc (phần xám ở hình trái) để tạo thành ma trận đầu ra O.

Trên thực tế, chúng ta sẽ thấy có 2 phép lọc ảnh là tương quan (correlation) và tích chập (convolution). Với phép tương quan, ma trận lọc sẽ đượt trượt đi và nhân với từng vùng của ảnh như trên. Tuy nhiên với phép tích chập, ma trận lọc sẽ được xoay 180 độ (theo cả chiều ngang và dọc) trước khi thực hiện nhân. 2 phép toán này là tương đương khi ma trận lọc đối xứng.

Với mỗi phép lọc ta có những ma trận lọc (Kernel) khác nhau, không có một quy định cụ thể nào cho việc xác định M. Kích thước ma trận M là một số lẻ. Ví dụ: 3x3, 5x5.

Khi nhân các phần tử tương ứng với nhau (giữa pixel, các điểm lân cận – các thành phần trong kernel), đối với các phần tử ở cạnh thì sẽ có một số pixel bị khuyết, lúc này, có nhiều cách giải quyết như bỏ qua, chèn thêm một (một số) hàng, cột mang giá trị 0 hoặc bằng giá trị gần nhất, hoặc tạo một đối xứng gương ở cạnh ảnh.

Tổng Tpt các phẩn tử trong ma trận M thường là 1.

  • Tpt > 1: Ảnh sau khi thực hiện xong phép lọc số ảnh (Idst) có độ sáng lớn hơn so với ảnh ban đầu (Isrc).
  • Tpt < 1: Ảnh sau khi thực hiện xong phép lọc số ảnh (Idst) có độ sáng nhỏ hơn so với ảnh ban đầu (Isrc).

Ví dụ

M=[1/91/91/91/91/91/91/91/91/9]M = \begin{bmatrix}1/9 & 1/9 & 1/9 \\\\ 1/9 & 1/9 & 1/9 \\\\ 1/9 & 1/9 & 1/9 \end{bmatrix}

B. Một số bộ lọc làm mịn ảnh

1. Lọc trung bình (Normalized Box Filter)

Đây là bộ lọc đơn giản nhất. Nó được xây dựng dựa trên ý tưởng tính giá trị một điểm ảnh bằng trung bình cộng các điểm ảnh xung quanh nó.

Ma trận lọc của lọc trung bình có dạng:

K=1K_width⋅K_height[111…1111…1⋅⋅⋅…1111…1]K = \frac{1}{K\_{width} \cdot K\_{height}} \begin{bmatrix} 1 & 1 & 1 & \ldots & 1 \\\\ 1 & 1 & 1 & \ldots & 1 \\\\ \cdot & \cdot & \cdot & \ldots & 1 \\\\ 1 & 1 & 1 & \ldots & 1 \end{bmatrix}

Cách lọc này thường được áp dụng cho làm trơn ảnh vẫn muốn giữ lại biên không bị mờ.

Code với Python - OpenCV: Đoạn code sau sẽ thực hiện lọc ảnh với ma trận lọc trung bình 5 x 5. Lưu ý: toàn bộ mã nguồn và hình ảnh dùng trong bài viết có thể được tải về tại liên kết trong mục

K=125[1111111111111111111111111]K = \frac{1}{25} \begin{bmatrix} 1 & 1 & 1 & 1 & 1 \\\\ 1 & 1 & 1 & 1 & 1 \\\\ 1 & 1 & 1 & 1 & 1 \\\\ 1 & 1 & 1 & 1 & 1 \\\\ 1 & 1 & 1 & 1 & 1 \end{bmatrix}

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# Load and blur image
img = cv.imread('rose_gauss.jpg')
img2 = cv.imread('rose_salt_and_pepper.jpg')
blur = cv.blur(img,(5,5))
blur2 = cv.blur(img2,(5,5))

# Convert color from bgr (OpenCV default) to rgb
img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
blur_rgb = cv.cvtColor(blur, cv.COLOR_BGR2RGB)
img_rgb2 = cv.cvtColor(img2, cv.COLOR_BGR2RGB)
blur_rgb2 = cv.cvtColor(blur2, cv.COLOR_BGR2RGB)

# Display
plt.subplot(221),plt.imshow(img_rgb),plt.title('Gauss Noise')
plt.xticks([]), plt.yticks([])
plt.subplot(222),plt.imshow(blur_rgb),plt.title('Gauss Noise - Blurred')
plt.xticks([]), plt.yticks([])
plt.subplot(223),plt.imshow(img_rgb2),plt.title('Salt&Pepper Noise')
plt.xticks([]), plt.yticks([])
plt.subplot(224),plt.imshow(blur_rgb2),plt.title('Salt&Pepper Noise - Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

Sau đây là kết quả sau khi chạy đoạn code trên:

Chú ý: bạn cần cài gói matplotlib (dùng pip) và tkinter để sử dụng với Python. Với Python 3.6, việc cài đặt tkinter có thể sử dụng:

sudo apt-get install python3.6-tk

Trên thực tế, thay vì sử dụng hàm cv2.blur() thì bộ lọc trung bình có thể được sử dụng với hàm: cv2.filter2D() với một tham số là ma trận lọc.

kernel = np.ones((5,5),np.float32)/25
blur = cv.filter2D(img,-1,kernel)

Khi thay ma trận lọc trung bình bằng một ma trận khác, chúng ta có thể có những phép lọc khác nhau.

2. Lọc Gauss (Gaussian Filter)

Bộ lọc Gauss được cho là bộ lọc hữu ích nhất, được thực hiện bằng cách nhân chập ảnh đầu vào với một ma trận lọc Gauss sau đó cộng chúng lại để tạo thành ảnh đầu ra.

Ý tưởng chung là giá trị mỗi điểm ảnh sẽ phụ thuộc nhiều vào các điểm ảnh ở gần hơn là các điểm ảnh ở xa. Trọng số của sự phụ thuộc được lấy theo hàm Gauss (cũng được sử dụng trong quy luật phân phối chuẩn).

Dưới đây là biểu diễn ma trận lọc Gauss:

Giả sử ảnh là một chiều. Điểm ảnh ở trung tâm sẽ có trọng số lớn nhất. Các điểm ảnh ở càng xa trung tâm sẽ có trọng số giảm dần khi khoảng cách từ chúng tới điểm trung tâm tăng lên. Như vậy điểm càng gần trung tâm sẽ càng đóng góp nhiều hơn vào giá trị điểm trung tâm.

Chú ý: Trên thực tế, việc lọc ảnh dựa trên hàm Gauss 2 chiều (ngang và dọc). Phân phối chuẩn 2 chiều có thể biểu diễn dưới dạng:

G0(x,y)=Ae−(x−μx)22σx2+−(y−μy)22σy2G_{0}(x, y) = A e^{ \dfrac{ -(x - \mu_{x}){2} }{ 2\sigma{2}_{x} } + \dfrac{ -(y - \mu_{y}){2} }{ 2\sigma{2}_{y} } }

Trong đó μ\mu là trung bình (đỉnh), σ2\sigma^{2} là phương sai của các biến số xx và yy.

Tham số μ\mu quyết định tác dụng của bộ lọc Gauss lên ảnh. Độ lớn của ma trận lọc (kernel) cần được lựa chọn cho đủ rộng.

Code thực tế lọc Gauss với Python - OpenCV: Trong OpenCV chúng ta sử dụng hàm sau để lọc Gauss: .

dst = cv.GaussianBlur(  src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]  )

Bạn cũng có thể tạo một ma trận lọc Gauss và sử dụng với hàm cv.filter2D() phía trên bằng cách sử dụng: .

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# Load and blur image
img = cv.imread('rose_gauss.jpg')
img2 = cv.imread('rose_salt_and_pepper.jpg')
blur = cv.GaussianBlur(img,(5,5),0)
blur2 = cv.GaussianBlur(img2,(5,5),0)

# Convert color from bgr (OpenCV default) to rgb
img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
blur_rgb = cv.cvtColor(blur, cv.COLOR_BGR2RGB)
img_rgb2 = cv.cvtColor(img2, cv.COLOR_BGR2RGB)
blur_rgb2 = cv.cvtColor(blur2, cv.COLOR_BGR2RGB)

# Display
plt.subplot(221),plt.imshow(img_rgb),plt.title('Gauss Noise')
plt.xticks([]), plt.yticks([])
plt.subplot(222),plt.imshow(blur_rgb),plt.title('Gauss Noise - Blurred')
plt.xticks([]), plt.yticks([])
plt.subplot(223),plt.imshow(img_rgb2),plt.title('Salt&Pepper Noise')
plt.xticks([]), plt.yticks([])
plt.subplot(224),plt.imshow(blur_rgb2),plt.title('Salt&Pepper Noise - Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

Dưới đây là kết quả lọc sử dụng phép lọc Gauss. Các bạn có thể thấy kết quả lọc (Gauss noise) rất tốt mà hình ảnh không bị nhòe nhiều như phép lọc trung bình như trên.

3. Lọc trung vị

Phép lọc trung vị cũng được thực hiện với các ma trận lọc. Tuy nhiên nó tính trung vị tất cả các giá trị điểm ảnh trong vùng ma trận lọc và sử dụng trung vị này cho giá trị điểm trung tâm. Một điều khá thú vị là với các cách lọc ở trên, giá trị điểm trung tâm được tính mới (có thể bằng hoặc khác với giá trị một điểm trong vùng ma trận lọc), còn với phép lọc trung vị, giá trị điểm trung tâm luôn được thay bằng một giá trị điểm ảnh trong bức ảnh đầu vào. Do vậy, phương pháp lọc này có khả năng loại bỏ nhiễu muối tiêu (salt-and-pepper noise ) khá tốt.

Có một điểm cũng cần được chú ý là phép lọc trung bình và lọc Gauss là phép lọc tuyến tính, nhưng phép lọc trung vị không phải là một phép lọc tuyến tính.

Để sử dụng lọc trung vị trong OpenCV, ta dùng hàm: cv.medianBlur().

Tương tự hai ví dụ ở trên, ta thay bước lọc thành:

blur = cv.medianBlur(img,5)

Kết quả thực hiện lọc trung vị với một số nhiễu:

Có thể thấy rõ, với việc lọc trung vị, nhiễu muối tiêu đã được loại bỏ tốt hơn nhiều so với lọc trung bình hay lọc Gauss.

4. Bộ lọc Bilateral (bộ lọc hai chiều)

là một bộ lọc hiệu quả cao trong việc loạt bỏ nhiễu mà vẫn giữ lại được các đường viền (cạnh) trong ảnh.

Như chúng ta đã biết, bộ lọc Gauss quyết định giá trị một điểm ảnh bằng cách lấy trung bình theo hàm Gauss các giá trị điểm ảnh xung quanh điểm đó. Hàm trọng số Gauss chỉ phụ thuộc vào khoảng cách trong không gian so với điểm ảnh trung tâm, không quan tâm đến sự tương quan giữa mức xám của điểm trung tâm với các điểm xung quanh đó. Nó cũng không quan tâm rằng điểm ảnh trung tâm có nằm tại một đường biên trong ảnh không, vì thế làm nhòe luôn các đường biên trong ảnh.

Bộ lọc Bilateral cũng sử dụng một bộ lọc Gauss với khoảng cách đến điểm trung tâm, đảm bảo chỉ có các điểm ở gần tham gia vào giá trị của điểm ảnh trung tâm. Tuy vậy nó sử dụng thêm một hàm Gauss cho mức xám, đảm bảo chỉ các điểm ảnh có mức xám tương đồng với điểm ảnh trung tâm tham gia vào quá trình làm mịn. Vì thế bộ lọc Bilateral bảo toàn được các đường biên trong ảnh bởi vì điểm ảnh ở biên có sự thay đổi về mức xám rất rõ ràng. Hơn nữa, thay vì hoạt động trên các kênh màu một cách riêng rẽ như bộ lọc trung bình hay bộ lọc Gauss, bộ lọc Bilateral có thể thi hành việc đo đạc màu sắc có chủ đích trong không gian màu CIE-Lab, làm mượt màu và bảo toàn các biên theo hướng phù hợp hơn với nhận thức con người.

Tuy vậy, bộ lọc Bilateral cũng có nhược điểm là chậm hơn các bộ lọc khác.

Sau đây là cách sử dụng bộ lọc Bilateral trong OpenCV:

blur = cv.bilateralFilter(img,9,75,75)

Kết quả: Hình 1 sử dụng phép lọc Bilateral, hình 2 sử dụng phéo lọc Gauss. Hãy thử chạy với các phép lọc khác nhé.

Như chúng ta có thể thấy, các texture được lọc rất tốt trong khi các đường biên trong ảnh vẫn được bảo toàn, không bị mờ đi.

Hình 1: Phép lọc Bilateral

Hình 2: Phép lọc Gauss

Các bạn có thể tìm hiểu thêm về bộ lọc Bilateral tại: http://people.csail.mit.edu/sparis/bf_course/.

C. Một số bộ lọc tìm biên ảnh

Ngoài việc làm mịn ảnh, một số bộ lọc còn có tác dụng tìm biên của ảnh.

1. Liên hệ giữa đạo hàm và biên ảnh

Xét vị dụ sau: Ta có một hình ảnh (1) với 2 biên đã được làm mờ. Hình (2) cho thấy mức xám tại đường quét màu đỏ của ảnh. Dễ dàng nhận thấy các đường biên ảnh chính là 2 vùng có sự thay đổi đột ngột về mức xám. Để xác định những sự thay đổi này, ta sử dụng đạo hàm của dải mức xám và tìm các cực trị (địa phương) trên đó. Có thể thấy rõ mối liên hệ giữa các cực trị địa phương của đạo hàm với các biên trong ảnh.

Liên hệ giữa đạo hàm và biên ảnh

2. Gradient của bức ảnh

Vậy là các biên của ảnh sẽ có quan hệ với đạo hàm theo chiều x và đạo hàm theo chiều y của mức xám. Gradient của ảnh là một đại lượng véc tơ hình thành từ 2 đạo hàm này và sẽ được sử dụng để lọc biên trong ảnh.

Công thức của Gradient là:

▽f=[∂f∂x,∂f∂y]\triangledown f = \begin{bmatrix} \frac{\partial f}{\partial x} , \frac{\partial f}{\partial y} \end{bmatrix}

3. Sobel và Scharr

Phép Sobel là sự kết hợp giữa làm mịn Gauss và phép vi phân, do vậy nó ít bị ảnh hưởng bởi nhiễu.

Việc kết hợp này không hẳn là việc lọc nhiễu bằng phép Gauss trước, rồi thực hiện Sobel để tìm biên mà phép Gauss và Sobel sẽ được kết hợp để tạo ra một ma trân lọc (kernel) rồi sau đó nhân chập ma trận này với ảnh. Hãy cùng xem tại sao có thể làm được như vậy:

Xét một hàm mức xám ff , ma trận lọc Gauss hh, ta có công thức:

∂∂x(h∗f)=(∂∂xh)∗f\frac{\partial}{\partial x}\left( h * f \right) =\left( \frac{\partial}{\partial x} h \right) * f

Như vậy, thay vì áp dụng bộ lọc Gauss lên ảnh (kích thước khá lớn) rồi áp dụng lọc Sobel để tìm biên, ta có thể áp dụng phép Sobel lên ma trận Gauss (kích thước nhỏ) rồi sau đó nhân chập ma trận thu được với ảnh để cho ra kết quả tương tự. Việc này sẽ giảm đáng kể chi phí tính toán.

Trong OpenCV, bạn có thể chỉ định được hướng đạo hàm (theo chiều ngang hay chiều dọc). Bạn cũng có thể chỉ định kích thước ma trận lọc với tham số ksize. Nếu ksize = -1, bộ lọc Scharr 3x3 sẽ được sử dụng thay vì Sobel 3x3 để có kết quả tốt hơn.

4. Laplacian

Laplacian được tính theo công thức:

Δsrc=∂2src∂x2+∂2src∂y2\Delta src = \frac{\partial ^2{src}}{\partial x^2} + \frac{\partial ^2{src}}{\partial y^2}

Với ksize = 1, ma trận lọc sẽ được sử dụng là:

kernel=[0101−41010]kernel = \begin{bmatrix} 0 & 1 & 0 \\\\ 1 & -4 & 1 \\\\ 0 & 1 & 0 \end{bmatrix}

Cài đặt Sobel và Laplace trong OpenCV:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('dave.jpg',0)
laplacian = cv.Laplacian(img,cv.CV_64F)
sobelx = cv.Sobel(img,cv.CV_64F,1,0,ksize=5)
sobely = cv.Sobel(img,cv.CV_64F,0,1,ksize=5)
plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray')
plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])
plt.show()

Kết quả:

Vấn đề quan trọng khi lập trình với Python - OpenCV:

Trong ví dụ cuối, kiểu dữ liệu đầu ra là cv.CV_8U hay np.uint8. Có một vấn đề với nó. Các chuyển dịch từ đen sang trắng (sự chuyển màu trên ảnh) có hệ số góc dương, các chuyển đổi từ trắng sang đen lại có hệ số góc âm. Do vậy, khi bạn chuyển dữ liệu sang np.uint8, các hệ số góc âm sẽ được chuyển thành 0. Do vậy bạn mất các cạnh ở chỗ màu sắc chuyển từ đen sang trắng.

Để nhận tất cả các đường biên, bạn phải chuyển kết quả sang kiểu cv.CV_16S, cv.CV_64F, hoặc một kiểu khác lưu trữ lớn hơn np.uint8, lấy giá trị tuyệt đối và chuyển lại về np.uint8.

Đoạn code dưới đây sẽ mô tả quá trình thực hiện. Ảnh đầu vào là một hình chữ nhật trắng trên nền đen. Ta thực hiện việc tìm cạnh theo chiều ngang (lấy các cạnh dọc). Nếu sử dụng kiểu dữ liệu np.uint8, cạnh bên phải bị mất (do cạnh đó được hình thành bởi sự chuyển dịch màu trắng -> đen). Để có cả 2 cạnh, ta phải làm như cách đã nêu trên.