簡體   English   中英

計算圖像兩半的像素比

[英]calculate the pixel ratio of two halves of an image

我正在嘗試計算沿其質心垂直和水平分割的兩半圖像的像素比。 目標是查看圖像的對稱/不對稱程度。 下面是代碼、原始圖像和顯示我正在嘗試執行的操作的圖像。

到目前為止,我已經對圖像進行了閾值處理,在其周邊創建了一個輪廓,填充了該輪廓,並計算並標記了質心。

我被困在如何(a)將輪廓分成兩部分,以及(b)計算輪廓圖像兩半之間的像素比(只是黑色部分。感謝您的任何建議和/或幫助。

# import packages
import argparse
import imutils
import cv2

# construct argument parser
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
    help="path to the input image")
args = vars(ap.parse_args())

# load the image
image = cv2.imread(args["image"])

# convert it to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# threshold the image
(T, threshInv) = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)

# find outer contour of thresholded image
cnts = cv2.findContours(threshInv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

# loop over the contour/s for image moments
for c in cnts:
    #  compute the center of the contour
    M = cv2.moments(c)
    #  calculate the centroid
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])

# draw and fill the contour on the image
cv2.drawContours(image, [c], -1, (0, 0, 0), thickness=cv2.FILLED)

# draw the centroid on the filled contour
cv2.circle(image, (cX, cY), 7, (255, 0, 0), -1)

# show the image
cv2.imshow("Image", image)
cv2.waitKey(0)

原圖:

在此處輸入圖像描述

目標:

在此處輸入圖像描述

第1部分:

圖片可以分別裁剪如下圖

top_half = image[0:cY, :]
bottom_half = image[cY:, :]

left_half = image[:, 0:cX]
right_half = image[:, cX:]

第2部分:

為了計算比率,讓我們只取上述 4 張裁剪圖像中的任何一個通道。 該通道將是僅由白色 (255) 像素和黑色 (0) 像素組成的二值圖像。 我們將計算每半個黑色像素的數量並除以:

top_half = top_half[:,:,1]
bottom_half = bottom_half[:,:,1]
left_half = left_half[:,:,1]
right_half = right_half[:,:,1]

以上都是單通道圖像

top_bottom_ratio = int(np.size(top_half) - np.count_nonzero(top_half) / np.size(bottom_half) - np.count_nonzero(bottom_half)

np.size()給出圖像中的像素總數

np.count_nonzero()給出白色像素的數量

你可以做同樣的事情來找到左右兩半之間的比例

感謝 Jeru Luke 的幫助。 使用他的建議,這段代碼解決了這個問題。

# import packages
import argparse
import imutils
import numpy as np
import cv2

# construct argument parser
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="path to the input image")
args = vars(ap.parse_args())

# load the image
image = cv2.imread(args["image"])

# convert it to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# threshold the image
(T, threshInv) = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)

# find outer contour of thresholded image
conts = cv2.findContours(threshInv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
conts = imutils.grab_contours(conts)

# loop over the contour/s for image moments
for c in conts:
    #  compute the center of the contour
    M = cv2.moments(c)
    #  calculate the centroid
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])

# draw and fill the contour on the image
cv2.drawContours(image, [c], -1, (0, 0, 0), thickness=cv2.FILLED)

# draw the centroid on the filled contour
cv2.circle(image, (cX, cY), 7, (255, 0, 0), -1)

# portions of the image (includes white and black pixels)
top_half = image[0:cY, :]
bottom_half = image[cY:, :]
left_half = image[:, 0:cX]
right_half = image[:, cX:]

# halves of images containing black pixels
top_half = top_half[:, :, 1]
bottom_half = bottom_half[:, :, 1]
left_half = left_half[:, :, 1]
right_half = right_half[:, :, 1]

#  np.size() gives total number of pixels in the image
#  np.count_nonzero() gives number of white pixels
top_bot_ratio = (int(np.size(top_half) - np.count_nonzero(top_half)) / (np.size(bottom_half) - np.count_nonzero(bottom_half)))
left_right_ratio = (int(np.size(left_half) - np.count_nonzero(left_half)) / (np.size(right_half) - np.count_nonzero(right_half)))

# area of the entire contour

# show the image
cv2.imshow("Original Image (grayscale)", gray)
cv2.imshow("Centroid", image)
cv2.imshow("Top Half (at the centroid)", top_half)
cv2.imshow("Bottom Half (at the centroid)", bottom_half)
cv2.imshow("Left Half (at the centroid)", left_half)
cv2.imshow("Right Half (at the centroid)", right_half)

print(f'The ratio of top to bottom halves is: {round(top_bot_ratio, 3)}')
print(f'The ratio of left to right halves is: {round(left_right_ratio, 3)}')
cv2.waitKey(0)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM