使用opencv python 进行农田分类和面积计算

使用python语言 通过用颜色区分图中的农田 并分为荒地 种植区 成熟区三类 并分别进行面积计算 !不要使用机器学习的算法!

img


最好用这个图片试试

图片RGB格式的吗?试一试这个:

import cv2
import numpy as np

# Load image and convert to RGB format
image = cv2.imread('farm_image.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# Define color ranges for each area
barren_land_color = ([0, 0, 0], [50, 50, 50])
planting_area_color = ([0, 200, 0], [50, 255, 50])
mature_area_color = ([200, 0, 0], [255, 50, 50])

# Create masks for each area
barren_land_mask = cv2.inRange(image, *barren_land_color)
planting_area_mask = cv2.inRange(image, *planting_area_color)
mature_area_mask = cv2.inRange(image, *mature_area_color)

# Calculate area for each mask
barren_land_area = np.count_nonzero(barren_land_mask)
planting_area = np.count_nonzero(planting_area_mask)
mature_area = np.count_nonzero(mature_area_mask)

# Print results
print("Barren land area:", barren_land_area)
print("Planting area:", planting_area)
print("Mature area:", mature_area)


该回答参考ChatGPT:
要实现通过颜色区分图中的农田并计算不同类别的面积,可以按照以下步骤:

  1. 读取图像并将其转换为RGB格式。
  2. 定义不同农田类型的颜色范围,例如荒地、种植区和成熟区的RGB值范围。
  3. 将图像转换为HSV格式,并使用cv2.inRange函数根据每个类型的颜色范围创建掩码。
  4. 对每个类型的掩码应用形态学操作,例如开操作或闭操作,以去除噪声和填充空洞。
  5. 使用cv2.findContours函数查找每个类型的轮廓。
  6. 计算每个类型的轮廓面积。

以下是示例代码:

import cv2
import numpy as np

# 读取图像并转换为RGB格式
img = cv2.imread('farm.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 定义颜色范围
barren_range = [(70, 70, 70), (100, 100, 100)]
planting_range = [(0, 100, 0), (50, 255, 50)]
mature_range = [(200, 150, 0), (255, 200, 50)]

# 将图像转换为HSV格式
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)

# 创建掩码
barren_mask = cv2.inRange(hsv, barren_range[0], barren_range[1])
planting_mask = cv2.inRange(hsv, planting_range[0], planting_range[1])
mature_mask = cv2.inRange(hsv, mature_range[0], mature_range[1])

# 对掩码进行形态学操作
kernel = np.ones((5, 5), np.uint8)
barren_mask = cv2.morphologyEx(barren_mask, cv2.MORPH_OPEN, kernel)
barren_mask = cv2.morphologyEx(barren_mask, cv2.MORPH_CLOSE, kernel)

planting_mask = cv2.morphologyEx(planting_mask, cv2.MORPH_OPEN, kernel)
planting_mask = cv2.morphologyEx(planting_mask, cv2.MORPH_CLOSE, kernel)

mature_mask = cv2.morphologyEx(mature_mask, cv2.MORPH_OPEN, kernel)
mature_mask = cv2.morphologyEx(mature_mask, cv2.MORPH_CLOSE, kernel)

# 查找轮廓并计算面积
contours, hierarchy = cv2.findContours(barren_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
barren_area = sum([cv2.contourArea(cnt) for cnt in contours])

contours, hierarchy = cv2.findContours(planting_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
planting_area = sum([cv2.contourArea(cnt) for cnt in contours])

contours, hierarchy = cv2.findContours(mature_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
mature_area = sum([cv2.contourArea(cnt) for cnt in contours])

print('荒地面积:', barren_area)
print('种植区面积:', planting_area)
print('成熟区面积:', mature_area)

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
可以使用 OpenCV 中的颜色空间转换和图像分割技术,对图像中的农田进行分类和面积计算。下面是一个示例代码,演示了如何对图像进行处理,实现农田分类和面积计算的功能。

import cv2
import numpy as np

# 读取图像
img = cv2.imread('field.jpg')

# 转换颜色空间
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 定义颜色范围
lower_brown = np.array([10, 50, 50])
upper_brown = np.array([30, 255, 255])
lower_green = np.array([30, 50, 50])
upper_green = np.array([90, 255, 255])

# 根据颜色范围进行图像分割
mask_brown = cv2.inRange(hsv, lower_brown, upper_brown)
mask_green = cv2.inRange(hsv, lower_green, upper_green)

# 对分割结果进行膨胀和腐蚀
kernel = np.ones((5, 5), np.uint8)
mask_brown = cv2.dilate(mask_brown, kernel, iterations=1)
mask_brown = cv2.erode(mask_brown, kernel, iterations=1)
mask_green = cv2.dilate(mask_green, kernel, iterations=1)
mask_green = cv2.erode(mask_green, kernel, iterations=1)

# 计算面积
pixel_area = img.shape[0] * img.shape[1]
brown_area = cv2.countNonZero(mask_brown)
green_area = cv2.countNonZero(mask_green)
barren_area = pixel_area - brown_area - green_area
mature_area = green_area * 0.2  # 假设成熟区面积为种植区的 20%

# 输出面积结果
print('荒地面积:', barren_area)
print('种植区面积:', green_area - mature_area)
print('成熟区面积:', mature_area)

在上述代码中,img 是输入的图像,lower_brownupper_brown 定义了荒地的颜色范围,lower_greenupper_green 定义了种植区和成熟区的颜色范围。通过调用 cv2.inRange 方法,可以根据颜色范围将图像分割成不同的区域。然后使用 cv2.dilatecv2.erode 方法对分割结果进行膨胀和腐蚀,以去除噪点和平滑边界。最后,通过调用 cv2.countNonZero 方法计算各个区域的像素数,进而计算面积。需要注意的是,这里假设成熟区面积为种植区的 20%,可以根据实际情况进行调整。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

基于ChatGPT的回答:
这个问题涉及到图像处理和计算几何,需要使用一些第三方库来实现。以下是一个可能的解决方案:

1、导入必要的库

import cv2
import numpy as np
from collections import defaultdict

2、读取图像并转换为HSV颜色空间


img = cv2.imread('farm.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

3、定义HSV颜色范围

# 荒地的颜色范围(黄色)
lower_yellow = np.array([20, 100, 100])
upper_yellow = np.array([30, 255, 255])

# 种植区的颜色范围(绿色)
lower_green = np.array([36, 25, 25])
upper_green = np.array([86, 255, 255])

# 成熟区的颜色范围(红色)
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])

4、根据颜色范围创建掩码

mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow)
mask_green = cv2.inRange(hsv, lower_green, upper_green)
mask_red = cv2.inRange(hsv, lower_red, upper_red)

5、对掩码进行形态学处理,以去除噪点


kernel = np.ones((5,5),np.uint8)
mask_yellow = cv2.morphologyEx(mask_yellow, cv2.MORPH_OPEN, kernel)
mask_green = cv2.morphologyEx(mask_green, cv2.MORPH_OPEN, kernel)
mask_red = cv2.morphologyEx(mask_red, cv2.MORPH_OPEN, kernel)

6、找到掩码中的轮廓,并根据轮廓面积分类

# 找到轮廓
contours_yellow, hierarchy = cv2.findContours(mask_yellow, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours_green, hierarchy = cv2.findContours(mask_green, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours_red, hierarchy = cv2.findContours(mask_red, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 分类
areas = defaultdict(int)
for cnt in contours_yellow:
    area = cv2.contourArea(cnt)
    if area > 100:
        areas['荒地'] += area
for cnt in contours_green:
    area = cv2.contourArea(cnt)
    if area > 100:
        areas['种植区'] += area
for cnt in contours_red:
    area = cv2.contourArea(cnt)
    if area > 100:
        areas['成熟区'] += area

输出结果

for k, v in areas.items():
    print(k, '面积:', v, '平方像素')

完整代码:

import cv2
import numpy as np
from collections import defaultdict

# 读取图像并转换为HSV颜色空间
img = cv2.imread('farm.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 荒地的颜色范围(黄色)
lower_yellow = np.array([20, 100, 100])
upper_yellow = np.array([30, 255, 255])

# 种植区的颜色范围(绿色)
lower_green = np.array([36, 25, 25])
upper_green = np.array([86, 255, 255])

# 成熟区的颜色范围(红色)
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])

# 根据颜色范围创建掩码
mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow)
mask_green = cv2.inRange(hsv, lower_green, upper_green)
mask_red = cv2.inRange(hsv, lower_red, upper_red)

# 对掩码进行形态学处理,以去除噪点
kernel = np.ones((5,5),np.uint8)
mask_yellow = cv2.morphologyEx(mask_yellow, cv2.MORPH_OPEN, kernel)
mask_green = cv2.morphologyEx(mask_green, cv2.MORPH_OPEN, kernel)
mask_red = cv2.morphologyEx(mask_red, cv2.MORPH_OPEN, kernel)

# 找到轮廓,并根据面积分类
contours_yellow, hierarchy = cv2.findContours(mask_yellow, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours_green, hierarchy = cv2.findContours(mask_green, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours_red, hierarchy = cv2.findContours(mask_red, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

areas = defaultdict(int)
for cnt in contours_yellow:
    area = cv2.contourArea(cnt)
    if area > 100:
        areas['荒地'] += area
for cnt in contours_green:
    area = cv2.contourArea(cnt)
    if area > 100:
        areas['种植区'] += area
for cnt in contours_red:
    area = cv2.contourArea(cnt)
    if area > 100:
        areas['成熟区'] += area

# 输出结果
for k, v in areas.items():
    print(k, '面积:', v, '平方像素')


以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先需要引入 opencv-python 库和 numpy 库:

import cv2
import numpy as np

然后读取图片:

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

接着,我们需要通过设定颜色阈值,将图像转化为二值图像。假设荒地的颜色为黑色,种植区的颜色为绿色,成熟区的颜色为黄色。

#设定阈值
thresh_h = [0, 0, 0]
thresh_l1 = [50, 50, 50]
thresh_l2 = [20, 100, 100]

#转化为 HSV 图像
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
#设定阈值并将图像二值化
thresh_img1 = cv2.inRange(hsv, np.array(thresh_h), np.array(thresh_l1))
thresh_img2 = cv2.inRange(hsv, np.array(thresh_l1), np.array(thresh_l2))
thresh_img = thresh_img1 + thresh_img2

这样就可以得到一个二值图像了,黑色的部分表示荒地,绿色的部分表示种植区,黄色的部分表示成熟区。

接下来需要计算面积。我们可以利用 opencv 内置的 findContours 函数,建立轮廓线,并计算轮廓线对应的面积。

#建立轮廓线
_, contours, _ = cv2.findContours(thresh_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#计算各轮廓线对应面积
for i, contour in enumerate(contours):
    area = cv2.contourArea(contour)
    if area < 100:
        #排除面积过小的噪点
        continue
    if area < 500:
        print('荒地面积:', area)
    elif area < 1000:
        print('种植区面积:', area)
    else:
        print('成熟区面积:', area)

完整代码如下:

import cv2
import numpy as np

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

#设定阈值
thresh_h = [0, 0, 0]
thresh_l1 = [50, 50, 50]
thresh_l2 = [20, 100, 100]

#转化为 HSV 图像
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
#设定阈值并将图像二值化
thresh_img1 = cv2.inRange(hsv, np.array(thresh_h), np.array(thresh_l1))
thresh_img2 = cv2.inRange(hsv, np.array(thresh_l1), np.array(thresh_l2))
thresh_img = thresh_img1 + thresh_img2

#建立轮廓线
_, contours, _ = cv2.findContours(thresh_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#计算各轮廓线对应面积
for i, contour in enumerate(contours):
    area = cv2.contourArea(contour)
    if area < 100:
        #排除面积过小的噪点
        continue
    if area < 500:
        print('荒地面积:', area)
    elif area < 1000:
        print('种植区面积:', area)
    else:
        print('成熟区面积:', area)

运行代码后,会输出各个区域的面积。

注意,此代码可能需要根据实际情况进行适当调整。
如果我的回答解决了您的问题,请采纳!

内容来源与ChatGpt4及newbing和百度:


首先,需要使用OpenCV库对图像进行处理。可以使用cv2.imread()函数读取图像,cv2.inRange()函数将图像中的颜色区分为不同的部分,通过二值化处理,得到荒地、种植区和成熟区的图像。然后使用cv2.findContours()函数找到图像中的轮廓,进而计算出各个区域的面积。

以下是示例代码:

import cv2

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

# 定义颜色范围
lower_green = (0, 100, 0)
upper_green = (50, 255, 50)
lower_yellow = (0, 150, 150)
upper_yellow = (50, 255, 255)

# 进行颜色分割
mask_green = cv2.inRange(img, lower_green, upper_green)
mask_yellow = cv2.inRange(img, lower_yellow, upper_yellow)
mask_brown = cv2.bitwise_not(cv2.bitwise_or(mask_green, mask_yellow))

# 找到轮廓并计算面积
contours_green, _ = cv2.findContours(mask_green, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
area_green = sum([cv2.contourArea(contour) for contour in contours_green])
contours_yellow, _ = cv2.findContours(mask_yellow, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
area_yellow = sum([cv2.contourArea(contour) for contour in contours_yellow])
contours_brown, _ = cv2.findContours(mask_brown, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
area_brown = sum([cv2.contourArea(contour) for contour in contours_brown])

print('荒地面积:', area_brown)
print('种植区面积:', area_yellow)
print('成熟区面积:', area_green)

需要注意的是,颜色范围的设定需要根据具体情况进行调整,以确保颜色分割的准确性。


祝您问题迎刃而解