[英]Calculating the area covered by the objects of irregular shapes in an image
通過創建二進制蒙版可以找到非黑色的圖像像素區域。 以像素為單位的面積等於蒙版中白色像素的總數。 一種獲取方法是計算圖像中白色像素的比例。 白色像素的數量將是圖像的分數*寬度*高度。 該分數只是圖像的平均值除以最大可能的灰度等級(255)。 所以
白色像素的像素面積=(平均值/ 255) 寬度高度
因此,獲得二進制掩膜圖像的分數平均值(平均值/ 255)(通過將閾值設置為0)。 平均值的結果將是一個單一值。 然后將其乘以圖像的寬度,再乘以圖像的高度。 該結果將等於蒙版中白色像素的總數,從而等於圖像中非黑色(即彩色)的像素總數。 白色像素數是圖像中非黑色像素的像素面積。
輸入:
import cv2
import numpy as np
img = cv2.imread('img.jpg')
height = img.shape[0]
width = img.shape[1]
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)
cv2.imshow("Mask", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
ave = cv2.mean(thresh)[0]/255
print(ave)
0.310184375
area = ave*height*width
print(area)
198518.0
請注意,這是非黑色像素區域。 您的某些矩形內部有黑色。 因此,這不是矩形的區域。 在隔離矩形以獲取矩形區域之前,您將確保圖像沒有黑色像素。
加成
Mark Setchell建議的一種更簡單的方法是簡單地計算閾值圖像中非零像素的數量。 它計算出與上述相同的數字。
import cv2
import numpy as np
img = cv2.imread('img.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)
cv2.imshow("Mask", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
area2 = cv2.countNonZero(thresh)
print(area2)
198518
補充2
如果您知道與圖像所覆蓋區域相對應的地面面積或尺寸(以米為單位,根據您的評論,一邊為0.8 m),那么與非零像素計數相對應的地面面積將為:
area on ground for nonzero pixels = count * 0.8 * 0.8 / (width * height)
其中寬度和高度是圖像的像素尺寸。
import cv2
import numpy as np
img = cv2.imread('img.jpg')
height = img.shape[0]
width = img.shape[1]
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)
cv2.imshow("Mask", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
count = cv2.countNonZero(thresh)
area = count*0.8*0.8/(width*height)
print(area)
0.19851800000000003
這樣的結果是0.198518平方米
希望這可以幫助😉
(0[Black] - 255[White])
60
使用cv2.threshold
cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
使用最小的內核(3,3)
填充小的白色斑點 碼
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('RIUXF.jpg',0)
hist = cv2.calcHist([img],[0],None,[256],[0,256])
# Area occupied by black region
black_area = np.true_divide(hist[0],np.prod(img.shape))[0]*100
# extract no black parts
thresh = cv2.threshold(img,60,255,cv2.THRESH_BINARY)[1]
kernel = np.ones((3,3),np.uint8)
# fill in the small white spots
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
# extract the contours
contours = cv2.findContours(opening, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[0]
blank_image = np.zeros((img.shape),np.uint8)
image_area = np.prod(img.shape)
# iterate through the contours detected from right top corner
for i,c in enumerate(contours[::-1]):
# turn blank_image black
blank_image *= 0
# draw filled contour
cv2.drawContours(blank_image, [c], 0, (255), thickness=cv2.FILLED)
contour_area = cv2.contourArea(c)
# percentage of area contour
contour_area_pc = np.true_divide(int(contour_area),image_area)*100 if int(contour_area) > 1 else 0
text = ' '.join(['Contour:',str(i),'Area:',str(round(contour_area,2)),'Percentage Area:',str(round(contour_area_pc,2))])
cv2.putText(blank_image,text,(10,60), cv2.FONT_HERSHEY_SIMPLEX, 1,(255),2,cv2.LINE_AA)
plt.imshow(blank_image, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
plt.show()
樣品輸出
PS:我懷疑cv2區域計算是否正確🤔
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.