亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 PIL 中選擇與圖像邊緣相鄰的所有黑色像素?

如何在 PIL 中選擇與圖像邊緣相鄰的所有黑色像素?

藍山帝景 2022-01-05 11:05:36
我有一組圖像培養皿,不幸的是不是最高質量(下面的示例,軸不是圖像的一部分)。我正在嘗試選擇背景并使用以下像素計算其面積:image = Image.open(path)black_image = 1 * (np.asarray(image.convert('L')) < 12)black_region = black_image.sum()這產生以下內容:如果我對黑色像素的選擇更嚴格,我會錯過其他圖像中的像素,如果我更寬松,我最終會選擇過多的培養皿本身。有沒有辦法我只能選擇亮度值小于 12 并且與邊緣相鄰的像素?我也對 openCV 解決方案持開放態度。
查看完整描述

2 回答

?
犯罪嫌疑人X

TA貢獻2080條經驗 獲得超4個贊

希望我沒有把問題簡單化,但從我的角度來看,使用 OpenCV 和簡單的閾值、形態學操作,findContours應該可以完成這項工作。


請看下面的代碼:


import cv2

import numpy as np


# Input

input = cv2.imread('images/x0ziO.png', cv2.IMREAD_COLOR)


# Input to grayscale

gray = cv2.cvtColor(input, cv2.COLOR_BGR2GRAY)


# Binary threshold

_, gray = cv2.threshold(gray, 20, 255, cv2.THRESH_BINARY)


# Morphological improvements of the mask

gray = cv2.morphologyEx(gray, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))

gray = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11)))


# Find contours

cnts, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)


# Filter large size contours; at the end, there should only be one left

largeCnts = []

for cnt in cnts:

    if (cv2.contourArea(cnt) > 10000):

        largeCnts.append(cnt)


# Draw (filled) contour(s)

gray = np.uint8(np.zeros(gray.shape))

gray = cv2.drawContours(gray, largeCnts, -1, 255, cv2.FILLED)


# Calculate background pixel area

bgArea = input.shape[0] * input.shape[1] - cv2.countNonZero(gray)


# Put result on input image

input = cv2.putText(input, 'Background area: ' + str(bgArea), (20, 30), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1.0, (255, 255, 255))


cv2.imwrite('images/output.png', input)

中間的“面具”圖像如下所示:

http://img1.sycdn.imooc.com//61d50b370001932a09190542.jpg

并且,最終輸出如下所示:


http://img1.sycdn.imooc.com//61d50b42000127ff09670544.jpg

查看完整回答
反對 回復 2022-01-05
?
隔江千里

TA貢獻1906條經驗 獲得超10個贊

由于您對 OpenCV 方法持開放態度,因此您可以使用 SimpleBlobDetector

顯然我得到的結果也不完美,因為有很多超參數需要設置。超參數使它非常靈活,因此是一個不錯的起點。

這就是 Detector 的作用(請參閱此處的詳細信息):

  1. 閾值:通過使用從 minThreshold 開始的閾值對源圖像進行閾值處理,將源圖像轉換為多個二值圖像。這些閾值遞增thresholdStep直到maxThreshold。所以第一個閾值是minThreshold,第二個是minThreshold + thresholdStep,第三個是minThreshold + 2 x thresholdStep,依此類推。

  2. 分組:在每個二值圖像中,連接的白色像素被分組在一起。讓我們稱這些為二進制 blob。

  3. 合并:計算二進制圖像中二進制 blob 的中心,并且比minDistBetweenBlobs合并位置更近的 blob 。

  4. 中心和半徑計算:計算并返回新合并的 blob 的中心和半徑。

找到圖片下方的代碼。

http://img1.sycdn.imooc.com//61d50b560001958508040540.jpg

# Standard imports

import cv2

import numpy as np


# Read image

im = cv2.imread("petri.png", cv2.IMREAD_COLOR)


# Setup SimpleBlobDetector parameters.

params = cv2.SimpleBlobDetector_Params()


# Change thresholds

params.minThreshold = 0

params.maxThreshold = 255


# Set edge gradient

params.thresholdStep = 5


# Filter by Area.

params.filterByArea = True

params.minArea = 10


# Set up the detector with default parameters.

detector = cv2.SimpleBlobDetector_create(params)


# Detect blobs.

keypoints = detector.detect(im)


# Draw detected blobs as red circles.

# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob

im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0, 0, 255),

                                      cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)


# Show keypoints

cv2.imshow("Keypoints", im_with_keypoints)

cv2.waitKey(0)


查看完整回答
反對 回復 2022-01-05
  • 2 回答
  • 0 關注
  • 282 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號