Python 使用opencv计算多个面积

Python 使用opencv计算多个面积,python,opencv,image-processing,Python,Opencv,Image Processing,我正在尝试使用opencv的轮廓面积计算图片中的不同区域,但没有取得多少成功。我正在使用的图片作为示例如下: 我的目标是计算表格的自由面积(灰色)和占用面积(橙色对象),并使用以下代码打印轮廓: img = cv2.imread('table.jpg', 1) b,g,r = cv2.split(img) imgRGB = cv2.merge([r,g,b]) hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) hsv_channels = cv2.spl

我正在尝试使用opencv的
轮廓面积
计算图片中的不同区域,但没有取得多少成功。我正在使用的图片作为示例如下:

我的目标是计算表格的自由面积(灰色)和占用面积(橙色对象),并使用以下代码打印轮廓:

img = cv2.imread('table.jpg', 1)

b,g,r = cv2.split(img)
imgRGB = cv2.merge([r,g,b])

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
hsv_channels = cv2.split(hsv)

rows = img.shape[0]
cols = img.shape[1]

for i in range(0, rows):
    for j in range(0, cols):
        h = hsv_channels[1][i][j]

        if h > 90 and h < 120:
            hsv_channels[2][i][j] = 255
        else:
            hsv_channels[2][i][j] = 0

image, contours, hierarchy = cv2.findContours(hsv_channels[2],cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
img1 = cv2.drawContours(imgRGB, contours, -1, (0,255,0), 3)
img=cv2.imread('table.jpg',1)
b、 g,r=cv2.分割(img)
imgRGB=cv2.merge([r,g,b])
hsv=cv2.CVT颜色(img,cv2.COLOR\U BGR2HSV)
hsv_通道=cv2.分离(hsv)
行=img.shape[0]
cols=图像形状[1]
对于范围(0,行)中的i:
对于范围内的j(0,cols):
h=hsv_频道[1][i][j]
如果h>90且h<120:
hsv_频道[2][i][j]=255
其他:
hsv_频道[2][i][j]=0
图像、轮廓、层次=cv2.findContours(hsv\u通道[2],cv2.RETR\u列表,cv2.CHAIN\u近似值\u简单值)
img1=cv2.绘制等高线(imgRGB,等高线,-1,(0255,0),3)
然而,我面临两个问题:

1-代码检测圆内的轮廓

2-给定多个轮廓,我不知道返回的区域是表的、对象的还是两者都有

有什么建议吗


非常感谢。

自从您转换到HSV色彩空间以来,您是否考虑过
cv2.inRange()
?之后,您可以使用
cv2.findContours()

例如:

import cv2
import numpy as np

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

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0,0,50])
upper = np.array([160,255,255])

mask = cv2.inRange(hsv, lower, upper)

res = cv2.bitwise_and(hsv,hsv, mask= mask)
gray = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

for i in contours:
    cnt = cv2.contourArea(i)
    if cnt > 1000:  
        cv2.drawContours(img, [i], 0, (0,0,0), -1)

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)
area = cv2.contourArea(cnt)
cv2.putText(img,'Gray area ='+str(area),(60,90), cv2.FONT_HERSHEY_COMPLEX, 0.5,(0,255,0),1,cv2.LINE_AA)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

编辑

计算百分比时:

import cv2
import numpy as np

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

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0,0,50])
upper = np.array([160,255,255])

# Calculate whole area
h,w = img.shape[:2]
whole_area_mask = np.ones((h, w), np.uint8)
ret, thresh = cv2.threshold(whole_area_mask,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)
whole_area = cv2.contourArea(cnt)

# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower, upper)

# Bitwise-AND mask and original image
res = cv2.bitwise_and(hsv,hsv, mask= mask)
gray = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

other_area = []
table_area = []

for i in contours:
    cnt = cv2.contourArea(i)
    M = cv2.moments(i)
    cx = int(M['m10']/M['m00'])
    if cnt > 1000:  
        cv2.drawContours(img, [i], 0, (0,0,0), -1)
        if w-100 > cx > 100:
            other_area.append(cnt)
        else:
            table_area.append(cnt)

# Percentage table/napkin/object 1/object 2
table_per = (100*(table_area[0]+table_area[1]))/whole_area
print('Table percentage: ', table_per)
napkin_per = (100*(whole_area-other_area[0]-other_area[1]-table_area[0]-table_area[1]))/whole_area
print('Napkin percentage: ', napkin_per)
first_object_per = (100*other_area[0])/whole_area
print('First object percentage: ', first_object_per)
second_object_per = (100*other_area[1])/whole_area
print('Second object percentage: ', second_object_per)
print('SUM: ', table_per+napkin_per+first_object_per+second_object_per)


cv2.imshow('img', img)
cv2.imwrite('tablest_res.png', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出:

表中百分比:9.875440996472028

餐巾百分比:58.93872849017208

第一对象百分比:28.055655475556

第二对象百分比:3.1301749586003313


SUM:100.0

自从您转换到HSV颜色空间以来,您是否考虑过
cv2.inRange()
?之后,您可以使用
cv2.findContours()

例如:

import cv2
import numpy as np

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

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0,0,50])
upper = np.array([160,255,255])

mask = cv2.inRange(hsv, lower, upper)

res = cv2.bitwise_and(hsv,hsv, mask= mask)
gray = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

for i in contours:
    cnt = cv2.contourArea(i)
    if cnt > 1000:  
        cv2.drawContours(img, [i], 0, (0,0,0), -1)

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)
area = cv2.contourArea(cnt)
cv2.putText(img,'Gray area ='+str(area),(60,90), cv2.FONT_HERSHEY_COMPLEX, 0.5,(0,255,0),1,cv2.LINE_AA)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

编辑

计算百分比时:

import cv2
import numpy as np

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

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0,0,50])
upper = np.array([160,255,255])

# Calculate whole area
h,w = img.shape[:2]
whole_area_mask = np.ones((h, w), np.uint8)
ret, thresh = cv2.threshold(whole_area_mask,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)
whole_area = cv2.contourArea(cnt)

# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower, upper)

# Bitwise-AND mask and original image
res = cv2.bitwise_and(hsv,hsv, mask= mask)
gray = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

other_area = []
table_area = []

for i in contours:
    cnt = cv2.contourArea(i)
    M = cv2.moments(i)
    cx = int(M['m10']/M['m00'])
    if cnt > 1000:  
        cv2.drawContours(img, [i], 0, (0,0,0), -1)
        if w-100 > cx > 100:
            other_area.append(cnt)
        else:
            table_area.append(cnt)

# Percentage table/napkin/object 1/object 2
table_per = (100*(table_area[0]+table_area[1]))/whole_area
print('Table percentage: ', table_per)
napkin_per = (100*(whole_area-other_area[0]-other_area[1]-table_area[0]-table_area[1]))/whole_area
print('Napkin percentage: ', napkin_per)
first_object_per = (100*other_area[0])/whole_area
print('First object percentage: ', first_object_per)
second_object_per = (100*other_area[1])/whole_area
print('Second object percentage: ', second_object_per)
print('SUM: ', table_per+napkin_per+first_object_per+second_object_per)


cv2.imshow('img', img)
cv2.imwrite('tablest_res.png', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出:

表中百分比:9.875440996472028

餐巾百分比:58.93872849017208

第一对象百分比:28.055655475556

第二对象百分比:3.1301749586003313


SUM:100.0

它真的只针对特定的图像吗?根据经验,你对你必须处理的图像(在橙色物体的位置上)有其他先验知识吗?这不仅适用于特定的图像,也适用于相似的图像,即表面上的多个物体(颜色非常不同)以及表面侧面的其他颜色(如本例中的地板),但我感兴趣的设置非常相似。它真的只针对那个特定的图像吗?根据经验,你对你必须处理的图像(在橙色物体的位置上)有其他先验知识吗?这不仅适用于特定的图像,也适用于相似的图像,即表面上的多个物体(颜色非常不同)以及表面侧面的其他颜色(如本例中的地板),但是我感兴趣的设置非常相似。非常感谢,这非常有效!有没有办法计算桌子的面积,这样我就可以得到使用/未使用面积的百分比?例如,当for循环中的if size>1000时,您就已经计算出了没有灰色餐巾的桌子的面积,您只需将其与放在餐巾纸上的两个圆形对象区分开来,然后简单地添加到餐巾纸区域(即餐巾纸+桌子区域)。然后简单地计算一下百分比。这非常有效,非常感谢!有没有办法计算桌子的面积,这样我就可以得到使用/未使用面积的百分比?例如,当for循环中的if size>1000时,您就已经计算出了没有灰色餐巾的桌子的面积,您只需将其与放在餐巾纸上的两个圆形对象区分开来,然后简单地添加到餐巾纸区域(即餐巾纸+桌子区域)。然后简单地计算百分比。