Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.

Ngưỡng OpenCV trong Python với cv2.threshold ()

Giới thiệu

Lập ngưỡng là một kỹ thuật đơn giản và hiệu quả để thực hiện phân đoạn cơ bản trong một hình ảnh và để mã hóa nó (biến nó thành một hình ảnh nhị phân) trong đó pixel là 0 or 1 (Hoặc 255 nếu bạn đang sử dụng số nguyên để đại diện cho chúng).

Thông thường, bạn có thể sử dụng tính năng tạo ngưỡng để thực hiện phân đoạn nền trước đơn giản trong một hình ảnh và nó tổng hợp thành các biến thể trên một kỹ thuật đơn giản cho mỗi pixel:

if pixel_value > threshold:
    pixel_value = MAX
else:
    pixel_value = 0

Quá trình thiết yếu này được gọi là Ngưỡng nhị phân. Bây giờ - có nhiều cách khác nhau để bạn có thể điều chỉnh ý tưởng chung này, bao gồm cả việc đảo ngược các hoạt động (chuyển đổi > ký với một < ký), thiết lập pixel_value đến threshold thay vì giá trị lớn nhất / 0 (được gọi là cắt ngắn), giữ nguyên pixel_value chính nó nếu nó ở trên threshold hoặc nếu nó ở dưới threshold.

Tất cả những điều này đã được triển khai một cách thuận tiện trong OpenCV như:

  • cv2.THRESH_BINARY
  • cv2.THRESH_BINARY_INV
  • cv2.THRESH_TRUNC
  • cv2.THRESH_TOZERO
  • cv2.THRESH_TOZERO_INV

… tương ứng. Đây là những phương pháp tương đối “ngây thơ” vì nó khá đơn giản, không tính đến ngữ cảnh trong hình ảnh, có kiến ​​thức về những hình dạng phổ biến, v.v. Đối với những thuộc tính này - chúng tôi sẽ phải sử dụng tính toán đắt tiền và mạnh mẽ hơn nhiều kỹ thuật.

Bây giờ, ngay cả với các phương pháp "ngây thơ" - một số heuristics có thể được áp dụng để tìm ra các ngưỡng tốt, và chúng bao gồm phương pháp Otsu và phương pháp Tam giác:

  • cv2.THRESH_OTSU
  • cv2.THRESH_TRIANGLE

Lưu ý: Lập ngưỡng OpenCV là một kỹ thuật thô sơ và nhạy cảm với sự thay đổi ánh sáng và độ chuyển màu, sự không đồng nhất về màu sắc, v.v. Tốt nhất là áp dụng cho các bức ảnh tương đối sạch, sau khi làm mờ chúng để giảm nhiễu, không có nhiều sự khác biệt về màu sắc trong các đối tượng bạn muốn phân đoạn.

Một cách khác để khắc phục một số vấn đề với tạo ngưỡng cơ bản với một giá trị ngưỡng duy nhất là sử dụng ngưỡng thích ứng áp dụng một giá trị ngưỡng trên từng khu vực nhỏ trong một hình ảnh, thay vì trên toàn cầu.

Định ngưỡng đơn giản với OpenCV

Tạo ngưỡng trong API Python của OpenCV được thực hiện thông qua cv2.threshold() phương thức - chấp nhận một hình ảnh (mảng NumPy, được biểu thị bằng số nguyên), ngưỡng, giá trị lớn nhất và phương pháp ngưỡng (cách thresholdmaximum_value được sử dụng):

img = cv2.imread('objects.jpg')

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)


blurred = cv2.GaussianBlur(img, (7, 7), 0)

ret, img_masked = cv2.threshold(blurred, 220, 255, cv2.THRESH_BINARY)

Mã trả lại chỉ là ngưỡng được áp dụng:

print(f"Threshold: {ret}") 

Đây, vì ngưỡng là 220 và chúng tôi đã sử dụng THRESH_BINARY phương pháp - mọi giá trị pixel ở trên 220 sẽ được tăng lên 255, trong khi mọi giá trị pixel bên dưới 220 sẽ được hạ xuống 0, tạo ra một hình ảnh đen trắng, với một “mặt nạ”, che các đối tượng ở nền trước.

Tại sao lại là 220? Biết hình ảnh trông như thế nào cho phép bạn đưa ra một số phỏng đoán gần đúng về ngưỡng bạn có thể chọn. Trong thực tế, hiếm khi bạn muốn đặt ngưỡng thủ công và chúng tôi sẽ đề cập đến việc lựa chọn ngưỡng tự động trong giây lát.

Hãy lập biểu đồ kết quả! Cửa sổ OpenCV có thể hơi phức tạp, vì vậy chúng tôi sẽ vẽ biểu đồ hình ảnh gốc, hình ảnh bị mờ và kết quả bằng Matplotlib:

fig, ax = plt.subplots(1, 3, figsize=(12, 8))
ax[0].imshow(img)
ax[1].imshow(blurred)
ax[2].imshow(img_masked)

Phương pháp ngưỡng

Như đã đề cập trước đó, có nhiều cách khác nhau để bạn có thể sử dụng ngưỡng và giá trị tối đa trong một hàm. Ban đầu chúng tôi đã xem xét ngưỡng nhị phân. Hãy tạo một danh sách các phương pháp và áp dụng từng phương pháp một, vẽ biểu đồ kết quả:

methods = [cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV, cv2.THRESH_TRUNC, cv2.THRESH_TOZERO, cv2.THRESH_TOZERO_INV]
names = ['Binary Threshold', 'Inverse Binary Threshold', 'Truncated Threshold', 'To-Zero Threshold', 'Inverse To-Zero Threshold']

def thresh(img_path, method, index):
    img = cv2.imread(img_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    blurred = cv2.GaussianBlur(img, (7, 7), 0)
    ret, img_masked = cv2.threshold(blurred, 220, 255, method)

    fig, ax = plt.subplots(1, 3, figsize=(12, 4))
    fig.suptitle(names[index], fontsize=18)
    ax[0].imshow(img)
    ax[1].imshow(blurred)
    ax[2].imshow(img_masked)
    plt.tight_layout()

for index, method in enumerate(methods):
    thresh('coins.jpeg', method, index)

THRESH_BINARYTHRESH_BINARY_INV là nghịch đảo của nhau và phân đôi một hình ảnh giữa 0255, gán chúng cho hậu cảnh và tiền cảnh tương ứng, và ngược lại.

THRESH_TRUNC phân chia hình ảnh giữa threshold255.

THRESH_TOZEROTHRESH_TOZERO_INV binarize giữa 0 và giá trị pixel hiện tại (src(x, y)). Hãy cùng xem những hình ảnh kết quả:

Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.

Xem hướng dẫn thực hành, thực tế của chúng tôi để học Git, với các phương pháp hay nhất, các tiêu chuẩn được ngành công nghiệp chấp nhận và bảng lừa đảo đi kèm. Dừng lệnh Googling Git và thực sự học nó!

Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.
Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.
Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.
Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.

Những phương pháp này đủ trực quan - nhưng, làm thế nào chúng ta có thể tự động hóa một giá trị ngưỡng tốt và giá trị "ngưỡng tốt" thậm chí có nghĩa là gì? Hầu hết các kết quả cho đến nay đều có mặt nạ không lý tưởng, với các vết và đốm trong đó. Điều này xảy ra do sự khác biệt về bề mặt phản chiếu của đồng xu - chúng không có màu đồng nhất do sự khác biệt về cách các đường gờ phản chiếu ánh sáng.

Ở một mức độ nào đó, chúng ta có thể chiến đấu với điều này bằng cách tìm ra ngưỡng toàn cầu tốt hơn.

Ngưỡng tự động / tối ưu hóa với OpenCV

OpenCV sử dụng hai phương pháp tìm kiếm ngưỡng toàn cục hiệu quả - phương pháp của Otsu và phương pháp Tam giác.

Phương pháp của Otsu giả định rằng nó đang hoạt động hai phương thức hình ảnh. Hình ảnh hai phương thức là hình ảnh có biểu đồ màu chỉ chứa hai đỉnh (tức là chỉ có hai giá trị pixel riêng biệt). Xem xét rằng mỗi đỉnh thuộc về một lớp chẳng hạn như “nền” và “tiền cảnh” - ngưỡng lý tưởng nằm ngay giữa chúng.

Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.
Ảnh: https://scipy-lectures.org/

Bạn có thể làm cho một số hình ảnh đa phương thức hơn với làm mờ gaussian, nhưng không phải tất cả.

Một giải thuật thay thế, đôi khi hoạt động tốt hơn là thuật toán tam giác, tính toán khoảng cách giữa tối đa và tối thiểu của biểu đồ mức xám và vẽ một đường thẳng. Điểm tại đó đường đó cách xa phần còn lại của biểu đồ một cách tối đa được chọn làm ngưỡng:

Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.

Cả hai điều này đều giả sử là một hình ảnh được chia tỷ lệ xám, vì vậy chúng tôi sẽ cần chuyển đổi hình ảnh đầu vào thành màu xám thông qua cv2.cvtColor():

img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)

ret, mask1 = cv2.threshold(blurred, 0, 255, cv2.THRESH_OTSU)
ret, mask2 = cv2.threshold(blurred, 0, 255, cv2.THRESH_TRIANGLE)

masked = cv2.bitwise_and(img, img, mask=mask1)

Hãy chạy hình ảnh qua cả hai phương pháp và hình dung kết quả:

methods = [cv2.THRESH_OTSU, cv2.THRESH_TRIANGLE]
names = ['Otsu Method', 'Triangle Method']

def thresh(img_path, method, index):
    img = cv2.imread(img_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (7, 7), 0)

    ret, img_masked = cv2.threshold(blurred, 0, 255, method)
    print(f"Threshold: {ret}")

    fig, ax = plt.subplots(1, 3, figsize=(12, 5))
    fig.suptitle(names[index], fontsize=18)
    ax[0].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    ax[1].imshow(cv2.cvtColor(gray, cv2.COLOR_BGR2RGB))
    ax[2].imshow(cv2.cvtColor(img_masked, cv2.COLOR_BGR2RGB))

for index, method in enumerate(methods):
    thresh('coins.jpeg', method, index)

Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.
Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.

Ở đây, phương pháp tam giác tốt hơn phương pháp của Otsu, bởi vì hình ảnh không phải là hai phương thức:

import numpy as np

img = cv2.imread('coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)

histogram_gray, bin_edges_gray = np.histogram(gray, bins=256, range=(0, 255))
histogram_blurred, bin_edges_blurred = np.histogram(blurred, bins=256, range=(0, 255))

fig, ax = plt.subplots(1, 2, figsize=(12, 4))

ax[0].plot(bin_edges_gray[0:-1], histogram_gray)
ax[1].plot(bin_edges_blurred[0:-1], histogram_blurred)

Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.

Tuy nhiên, rõ ràng là phương pháp tam giác có thể hoạt động với hình ảnh như thế nào và tạo ra kết quả hài lòng hơn.

Hạn chế của Ngưỡng OpenCV

Tạo ngưỡng với OpenCV rất đơn giản, dễ dàng và hiệu quả. Tuy nhiên, nó khá hạn chế. Ngay sau khi bạn giới thiệu các yếu tố đầy màu sắc, nền không đồng nhất và điều kiện ánh sáng thay đổi - ngưỡng toàn cầu như một khái niệm trở nên quá cứng nhắc.

Hình ảnh thường quá phức tạp đối với một ngưỡng duy nhất là đủ và điều này có thể được giải quyết một phần thông qua ngưỡng thích ứng, trong đó nhiều ngưỡng cục bộ được áp dụng thay vì một ngưỡng toàn cầu. Mặc dù cũng có giới hạn, nhưng ngưỡng thích ứng linh hoạt hơn nhiều so với ngưỡng toàn cầu.

Kết luận

Trong những năm gần đây, phân đoạn nhị phân (như những gì chúng tôi đã làm ở đây) và phân đoạn đa nhãn (nơi bạn có thể mã hóa số lớp tùy ý) đã được mô hình hóa thành công với mạng học sâu, mạnh mẽ và linh hoạt hơn nhiều. Ngoài ra, họ có thể mã hóa ngữ cảnh toàn cầu và cục bộ thành các hình ảnh mà họ đang phân đoạn. Nhược điểm là - bạn cần dữ liệu để đào tạo họ, cũng như thời gian và kiến ​​thức chuyên môn.

Để tạo ngưỡng đơn giản, nhanh chóng, bạn có thể sử dụng OpenCV. Để phân đoạn chính xác, cấp độ sản xuất, bạn sẽ muốn sử dụng mạng thần kinh.

Tiến xa hơn - Học sâu thực tế cho thị giác máy tính

Bản tính ham học hỏi của bạn khiến bạn muốn tiến xa hơn? Chúng tôi khuyên bạn nên kiểm tra Khóa học: “Học sâu thực tế cho thị giác máy tính với Python”.

Ngưỡng OpenCV trong Python với cv2.threshold() PlatoBlockchain Data Intelligence. Tìm kiếm dọc. Ái.

Một khóa học thị giác máy tính khác?

Chúng tôi sẽ không phân loại các chữ số MNIST hoặc thời trang MNIST. Họ đã phục vụ phần của họ từ lâu lắm rồi. Quá nhiều tài nguyên học tập đang tập trung vào bộ dữ liệu cơ bản và kiến ​​trúc cơ bản trước khi để các kiến ​​trúc hộp đen nâng cao gánh vác gánh nặng về hiệu suất.

Chúng tôi muốn tập trung vào sự làm sáng tỏ, tính thực tiễn, sự hiểu biết, trực giácdự án thực tế. Muốn học làm thế nào Bạn có thể làm nên điều khác biệt? Chúng tôi sẽ đưa bạn đi từ cách bộ não của chúng ta xử lý hình ảnh để viết một bộ phân loại học sâu cấp độ nghiên cứu cho bệnh ung thư vú đến mạng lưới học tập sâu "ảo giác", dạy cho bạn các nguyên tắc và lý thuyết thông qua công việc thực tế, trang bị cho bạn bí quyết và công cụ để trở thành chuyên gia ứng dụng học sâu để giải quyết vấn đề thị giác máy tính.

Có gì bên trong?

  • Các nguyên tắc đầu tiên của tầm nhìn và cách máy tính có thể được dạy để "nhìn"
  • Các tác vụ và ứng dụng khác nhau của thị giác máy tính
  • Các công cụ giao dịch sẽ giúp công việc của bạn dễ dàng hơn
  • Tìm kiếm, tạo và sử dụng bộ dữ liệu cho thị giác máy tính
  • Lý thuyết và ứng dụng của Mạng nơ ron chuyển đổi
  • Xử lý sự thay đổi tên miền, đồng xuất hiện và các sai lệch khác trong tập dữ liệu
  • Chuyển giao Học tập và tận dụng thời gian đào tạo cũng như các tài nguyên tính toán của người khác vì lợi ích của bạn
  • Xây dựng và đào tạo một máy phân loại ung thư vú tiên tiến nhất
  • Cách áp dụng liều lượng hoài nghi lành mạnh vào các ý tưởng chủ đạo và hiểu được hàm ý của các kỹ thuật được áp dụng rộng rãi
  • Hình dung “không gian khái niệm” của ConvNet bằng t-SNE và PCA
  • Các nghiên cứu điển hình về cách các công ty sử dụng kỹ thuật thị giác máy tính để đạt được kết quả tốt hơn
  • Đánh giá mô hình thích hợp, hình dung không gian tiềm ẩn và xác định sự chú ý của mô hình
  • Thực hiện nghiên cứu miền, xử lý tập dữ liệu của riêng bạn và thiết lập các thử nghiệm mô hình
  • Các kiến ​​trúc tiên tiến, sự phát triển của các ý tưởng, điều gì làm cho chúng trở nên độc đáo và cách thực hiện chúng
  • KerasCV - một thư viện WIP để tạo các mô hình và đường ống hiện đại
  • Cách phân tích cú pháp và đọc các bài báo và tự thực hiện chúng
  • Lựa chọn mô hình tùy thuộc vào ứng dụng của bạn
  • Tạo một đường dẫn học máy từ đầu đến cuối
  • Phong cảnh và trực giác khi phát hiện đối tượng với R-CNN, RetinaNets, SSD và YOLO nhanh hơn
  • Phân đoạn phiên bản và ngữ nghĩa
  • Nhận dạng đối tượng trong thời gian thực với YOLOv5
  • Đào tạo máy dò đối tượng YOLOv5
  • Làm việc với Máy biến áp bằng KerasNLP (thư viện WIP dành cho ngành công nghiệp)
  • Tích hợp Transformers với ConvNets để tạo phụ đề cho hình ảnh
  • Ngủ sâu
  • Tối ưu hóa mô hình Deep Learning cho thị giác máy tính

Dấu thời gian:

Thêm từ xếp chồng lên nhau