[英]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.