用python语言,使用特征提取的方法分类,分类完成后进行面积计算
# 轮廓/形状检测
import cv2
import numpy as np
# 图像排列处理函数
def stackImages(scale, imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range(0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver
def getContours(img):
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 使用cv点查找轮廓(传入图像对象和检测范围参数)
for cnt in contours:
area = cv2.contourArea(cnt)
print(area)
if area > 500: # 设置检测阈值
cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3) # 将复制图像放上面,从而框出
peri = cv2.arcLength(cnt, True) # 计算周长(轮廓长度)检测外围轮廓
# print(peri)
approx = cv2.approxPolyDP(cnt, 0.02*peri, True) # 统计拐点个数,通过拐点个数确认图形形状
print(len(approx)) # 打印其长度,3是三角,4是长方形
objCor = len(approx) # 检测边界框
x, y, w, h = cv2.boundingRect(approx) # 得到xy和对象长宽
# 对象类型名称设置:
if objCor == 3:
objectType = "Tri"
elif objCor == 4:
aspRatio = w/float(h)
if aspRatio > 0.98 and aspRatio < 1.03:
objectType = "Square"
else:
objectType = "Rectangle"
elif objCor > 4:
objectType = "Circles"
else:
objectType = "None"
cv2.rectangle(imgContour, (x, y), (x+w, y+h), (0, 255, 0), 2) # 绘制框,位置宽高(边界框)
cv2.putText(imgContour, objectType,
(x+(w//2)-10, y+(h//2)-10), cv2.FONT_HERSHEY_COMPLEX, 0.7,
(0, 0, 0), 2) # 设置脚本文字(进行了偏移),字体颜色,大小,颜色,粗细
path = '5.png' # 设置资源文件夹
img = cv2.imread(path)
imgContour = img.copy()
# 预处理,转化为灰度,检测拐角点
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 频道为白色,BG设置为灰色
imgBlur = cv2.GaussianBlur(imgGray, (7, 7), 1) # 高斯模糊函数,定义内核,设置sigma
imgCanny = cv2.Canny(imgBlur, 50, 50) # 边缘检测器
getContours(imgCanny)
imgBlank = np.zeros_like(img) # 创建空白图像
imgStack = stackImages(0.5, ([img, imgGray, imgBlur],
[imgCanny, imgContour, imgBlank]))
cv2.imshow('Stack', imgStack)
cv2.waitKey(0)
该回答引用于gpt与OKX安生共同编写:
针对农田分类和面积计算问题,可以借助OpenCV库和Python语言实现。可以使用以下步骤进行处理:
import cv2
img = cv2.imread('field.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
opened = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
contours, hierarchy = cv2.findContours(opened, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
min_area = 1000
fields = []
for contour in contours:
area = cv2.contourArea(contour)
if area > min_area:
fields.append(contour)
result = img.copy()
for field in fields:
cv2.drawContours(result, [field], -1, (0, 0, 255), 2)
print('农田数量:', len(fields))
for i, field in enumerate(fields):
area = cv2.contourArea(field)
print('农田{}面积为: {}平方像素'.format(i+1, area))
import cv2
import numpy as np
from sklearn.ensemble import RandomForestClassifier
# 定义GLCM算法相关参数
distance = 1
angle = 0
levels = 256
symmetric = True
normed = True
# 计算农田区域的纹理特征
def calculate_texture_features(img):
# 计算图像的GLCM矩阵
glcm = cv2.calcGLCM(img, [distance], [angle], levels, symmetric, normed)
# 提取GLCM统计数据
contrast = cv2.compareHist(glcm[:, :, 0], np.array([1]), method=cv2.HISTCMP_CHISQR_ALT)
dissimilarity = cv2.compareHist(glcm[:, :, 1], np.array([1]), method=cv2.HISTCMP_CHISQR_ALT)
homogeneity = cv2.compareHist(glcm[:, :, 2], np.array([1]), method=cv2.HISTCMP_CHISQR_ALT)
energy = cv2.compareHist(glcm[:, :, 3], np.array([1]), method=cv2.HISTCMP_CHISQR_ALT)
correlation = cv2.compareHist(glcm[:, :, 4], np.array([1]), method=cv2.HISTCMP_CHISQR_ALT)
# 返回纹理特征向量
return np.array([contrast, dissimilarity, homogeneity, energy, correlation])
# 加载农田图像和类别标签
X = []
y = []
for i in range(1, 101):
img = cv2.imread(f"farm_{i}.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
X.append(calculate_texture_features(gray))
if i <= 50:
y.append(0) # Wheat类别
else:
y.append(1) # Corn类别
# 训练随机森林分类器
clf = RandomForestClassifier(n_estimators=100)
clf.fit(X, y)
# 加载新的农田图像,进行分类和面积计算
img = cv2.imread("new_farm.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 对农田图像进行分割,获取每个农田区域
fields = get_fields(gray)
# 遍历每个农田区域,计算其面积和类别
total_area = 0
wheat_area = 0
corn_area = 0
for field in fields:
# 计算农田区域的纹理特征
features = calculate_texture_features(field)
# 对农田区域进行分类
prediction = clf.predict([features])[0]
if prediction == 0:
wheat_area += area(field)
else:
corn_area += area(field)
# 更新总面积
total_area += area(field)
# 输出结果
print(f"Total area: {total_area} square meters")
print(f"Wheat area: {wheat_area} square meters")
print(f"Corn area: {corn_area} square meters")
该回答参考ChatGPT:
使用OpenCV对农田进行分类和面积计算可以分为以下几个步骤:
收集和准备数据。收集拍摄的农田图像,并对图像进行预处理,如裁剪、去噪、灰度化、二值化等操作。
提取纹理特征。使用OpenCV的纹理分析函数,如LBP、GLCM等,提取图像的纹理特征。这些纹理特征可以用于分类和面积计算。
分类器训练。将提取的纹理特征作为分类器的输入,训练一个分类器,如支持向量机(SVM)、k-近邻(k-NN)等。训练好的分类器可以用于对新的农田图像进行分类。
分类和面积计算。使用训练好的分类器对新的农田图像进行分类,并将分类结果与图像面积相乘,即可得到该类农田的总面积。重复这个过程,即可对不同类别的农田进行分类和面积计算。
下面是一个使用OpenCV进行纹理分类和面积计算的示例代码:
import cv2
import numpy as np
# 读取图像
img = cv2.imread('field.jpg')
# 预处理图像
img = img[100:400, 100:400] # 裁剪
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度化
gray = cv2.medianBlur(gray, 5) # 中值滤波
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) # 二值化
# 提取纹理特征
radius = 1
n_points = 8 * radius
lbp = cv2.xfeatures2d.SIFT_create()
kp = lbp.detect(gray, None)
kp, des = lbp.compute(gray, kp)
# 训练分类器
trainData = np.float32(des)
responses = np.array([0, 1]) # 假设有两种不同的农田类型
svm = cv2.ml.SVM_create()
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setTermCriteria((cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-6))
svm.train(trainData, cv2.ml.ROW_SAMPLE, responses)
# 分类和面积计算
img_area = img.shape[0] * img.shape[1]
classes = ['Type1', 'Type2']
for i, classname in enumerate(classes):
mask = np.zeros_like(gray)
mask[thresh == 255] = 1
mask[svm.predict(des) != i] = 0
class_area = np.sum(mask) / img_area
print('{}: {:.2f}'.format(classname, class_area))
基于最新版ChatGPT4的回答,望采纳!!!有其他问题也可以询问我哦💕(最新版更智能,功能更加强大):
进行农田分类和面积计算,可以使用 OpenCV 进行图像处理和特征提取。下面是一个简单的流程:
加载图像并进行预处理:首先使用 OpenCV 的 imread() 函数加载图像,并对其进行必要的预处理操作,例如去噪、平滑、灰度化等。
特征提取:通过纹理特征提取技术,如局部二值模式(LBP)、灰度共生矩阵(GLCM)或Gabor滤波器等方法,从图像中提取纹理特征,将每个像素点的纹理信息转换为特定的特征向量,作为输入样本的特征表示。
训练分类器:使用机器学习算法,如支持向量机(SVM)或随机森林(Random Forest),对样本进行训练,构建分类器模型。
分类:使用分类器对新的农田图像进行分类,将其分为不同的农田类型。
面积计算:根据分类结果,使用 OpenCV 的轮廓检测功能计算出各个农田区域的边界,并计算每个农田区域的面积。
下面是一个简单的代码示例,仅供参考:
python
import cv2
# 读取图像
img = cv2.imread('farm.png')
# 灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# LBP特征提取
lbp = cv2.xfeatures2d.SIFT_create()
keypoints, descriptors = lbp.detectAndCompute(gray, None)
# 构建SVM分类器模型并训练
svm = cv2.ml.SVM_create()
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.trainAuto(descriptors, cv2.ml.ROW_SAMPLE, labels)
# 对新图像进行分类
test_img = cv2.imread('test_farm.png')
test_gray = cv2.cvtColor(test_img, cv2.COLOR_BGR2GRAY)
test_keypoints, test_descriptors = lbp.detectAndCompute(test_gray, None)
result = svm.predict(test_descriptors)
# 计算面积
contours, hierarchy = cv2.findContours(result, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
area = cv2.contourArea(contour)
print("农田面积为:", area)
需要注意的是,这只是一个简单的示例代码,实际应用中还需要根据具体情况进行调整和优化。同时,纹理特征提取方法、机器学习算法和分类器参数等也会对分类结果和面积计算产生影响,需要根据实际情况进行选择和调整。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
实现农田分类和面积计算,可以分为以下步骤:
图像预处理:将农田图像进行预处理,包括灰度化、滤波、边缘检测等。
特征提取:从预处理后的图像中提取特征,比如纹理特征、形状特征等。
分类器训练:利用已标注的农田图像和其对应的类别信息,训练分类器模型,比如支持向量机(SVM)、决策树(Decision Tree)等。分类器模型将根据输入的图像特征,判断该图像属于哪一类别。
分类结果输出:对新的农田图像进行分类,输出分类结果。
面积计算:依据分类后的结果,利用数学公式计算各类别农田面积。
下面是一份伪代码:
import cv2
import numpy as np
# 1.图像预处理
img = cv2.imread("field_image.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 2.提取纹理特征
lbp = cv2.xfeatures2d.SIFT_create()
# 计算LBP特征
keypoints, descriptors = lbp.detectAndCompute(blurred, None)
# 3.分类器训练
# 建立分类器模型
svm = cv2.ml.SVM_create()
# 准备训练数据
X_train = descriptors
y_train = np.array([0, 0, 1, 1]) # 假设有4张图像,前面两张属于类别0,后面两张属于类别1
# 训练分类器
svm.trainAuto(X_train, cv2.ml.ROW_SAMPLE, y_train)
# 4.分类结果输出
# 对新的农田图像进行分类
keypoints2, descriptors2 = lbp.detectAndCompute(new_image, None)
result = svm.predict(descriptors2)
# 5.面积计算
# 假设分类0表示农田,1表示非农田
field_mask = result == 0 # 获取农田区域的掩码
field_area = np.count_nonzero(field_mask) # 计算农田面积,单位为像素
以上代码仅供参考,具体实现中需要根据实际情况进行调整。
如果我的回答解决了您的问题,请采纳!