基于OpenCV的图形分析辨认04

news/2025/3/14 18:24:22/

目录

一、前言

二、实验目的

三、实验内容

四、实验过程


一、前言

编程语言:Python,编程软件:vscode或pycharm,必备的第三方库:OpenCV,numpy,matplotlib,os等等。

关于OpenCV,numpy,matplotlib,os等第三方库的下载方式如下:

第一步,按住【Windows】和【R】调出运行界面,输入【cmd】,回车打开命令行。

第二步,输入以下安装命令(可以先升级一下pip指令)。

pip升级指令:

python -m pip install --upgrade pip

 opencv库的清华源下载:

pip install opencv-python  -i https://pypi.tuna.tsinghua.edu.cn/simple

numpy库的清华源下载:

 pip install numpy  -i https://pypi.tuna.tsinghua.edu.cn/simple

matplotlib库的清华源下载:

pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

os库的清华源下载:

pip install os  -i https://pypi.tuna.tsinghua.edu.cn/simple 

二、实验目的

1.了解不同图像分割算法;

2.基于函式库,透过调用函式,实现图像分割;

3.基于演算法原理,以函数形式,自行实现图像分割;

三、实验内容

1.任选一张彩色图,透过调用函式(库)完成完成课堂教授内容

(1)Otsu:(1)灰度图分割

(2)Clustering:(1)灰度图分割(2)彩色图像分割

2.任选一张彩色图,透过演算法,自行撰写函式完成完成课堂教授内容

(1)Otsu:(1)灰度图分割

(2)Clustering:(1)灰度图分割(2)彩色图像分割

四、实验过程

(1)基于OpenCV库,使用大津法和kmeans聚类解决问题一,代码如下:

import cv2
import numpy as np
import matplotlib.pyplot as pltdef question1_Otsu():# 读取图像img = cv2.imread(r"D:\Image\img1.jpg")# 转换为灰度图像img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 对图像进行二值化处理(OTSU算法)thresh1, result1 = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 对图像进行反向二值化处理(OTSU算法)thresh2, result2 = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)# 绘制原始图像、灰度图像、二值化图像、反向二值化图像plt.subplot(2, 2, 1), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title('Original img'), plt.axis('off')plt.subplot(2, 2, 2), plt.imshow(img_gray, cmap = 'gray'), plt.title('Gray img'), plt.axis('off')plt.subplot(2, 2, 3), plt.imshow(result1, cmap = 'gray'), plt.title('Binary img'), plt.axis('off')plt.subplot(2, 2, 4), plt.imshow(result2, cmap = 'gray'), plt.title('Inverse binary img'), plt.axis('off')# 调整图像布局并显示图像plt.tight_layout()plt.show()def question1_Clustering_gray():# 读取图像并转换为灰度图像img = cv2.imread(r"D:\Image\img1.jpg", 0)# 获取图像的高度和宽度height, width = img.shape[:]# 将图像转换为一维数组data = img.reshape((-1, 1))# 将数据转换为浮点型data = np.float32(data)# 设置聚类停止条件criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.1)# 设置聚类中心的初始化方式flags = cv2.KMEANS_RANDOM_CENTERS# 循环不同的聚类数for k in range(1, 10):if k == 1:# 展示原始图像plt.subplot(3, 3, k), plt.imshow(img, cmap = 'gray'), plt.title('Original img'), plt.axis('off')else:# 执行k-means聚类算法compactness, labels, centers = cv2.kmeans(data, k, None, criteria, 10, flags)# 重构聚类结果图像img_k = labels.reshape((height, width))# 展示聚类结果图像plt.subplot(3, 3, k), plt.imshow(img_k, cmap = 'gray'), plt.title(f'Kmeans img (k={k})'), plt.axis('off')# 调整图像布局并显示图像plt.tight_layout()plt.show()def question1_Clustering_color():# 读取图片img = cv2.imread(r"D:\Image\img1.jpg")# 将图片转换为numpy数组,并进行形状变换,转化成3列data = img.reshape((-1, 3))# 转换为浮点型data = np.float32(data)# 设置聚类停止条件criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.1)# 设置聚类中心的初始化方式flags = cv2.KMEANS_RANDOM_CENTERS# 不同的K值列表K_list = [1, 2, 4, 8, 16, 32]# 遍历不同的K值for k in range(len(K_list)):# 第一个K值特殊处理if k == 0:# 显示原始图片plt.subplot(2, 3, k + 1), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title('Original img'), plt.axis('off')else:# k-means聚类compactness, labels, centers = cv2.kmeans(data, K_list[k], None, criteria, 10, flags)# 将中心点转换为整型centers = np.uint8(centers)# 根据中心点和标签得到聚类结果res = centers[labels.flatten()]# 重构聚类结果图像img_k = res.reshape((img.shape))# 显示聚类结果图片plt.subplot(2, 3, k + 1), plt.imshow(cv2.cvtColor(img_k, cv2.COLOR_BGR2RGB)), plt.title(f'Kmeans img (k={K_list[k]})'), plt.axis('off')# 调整图像布局并显示图像plt.tight_layout()plt.show()# 执行相应函数
question1_Otsu()
question1_Clustering_gray()
question1_Clustering_color()

代码的运行效果如下:

基于Otsu的灰度图分割:

基于kmeans的灰度图分割:

基于kmeans的彩色图分割:

(2)不使用OpenCV库,根据otsu和kmeans的原理,编写代码文件,命名为【Methods】,具体代码如下:

import numpy as npdef Otsu(img):# 复制图像数据data = img.copy()# 将数据转换为float32类型data = np.float32(data)# 获取图像的高度和宽度height, width = img.shape[:]# 初始化阈值和最大类间方差threshold_t = 0otsu_max = 0# 遍历255以内的每个灰度值for t in range(256):# 选取像素值小于等于阈值的像素点n0 = data[np.where(data <= t)]# 选取像素值大于阈值的像素点n1 = data[np.where(data > t)]# 计算像素点权重weight0 = len(n0) / (height * width)weight1 = len(n1) / (height * width)# 计算均值u0 = np.mean(n0) if len(n0) > 0 else 0.u1 = np.mean(n1) if len(n1) > 0 else 0.# 计算类间方差otsu = weight0 * weight1 * (u0 - u1) ** 2# 更新最大类间方差和阈值if otsu > otsu_max:otsu_max = otsuthreshold_t = tprint('类间方差最大阈值:', threshold_t)# 将像素值小于等于阈值的像素点设为0data[data <= threshold_t] = 0# 将像素值大于阈值的像素点设为255data[data > threshold_t] = 255# 将数据转换为uint8类型img_result = np.uint8(data)return img_resultdef Kmeans(img, k, iter):# 判断图像是否为灰度图像if len(img.shape) == 2:# 获取图像高度和宽度height, width = img.shape[:]# 将图片转换为numpy数组,并进行形状变换,转化成1列data = img.reshape((-1, 1))else:# 获取图像高度和宽度height, width = img.shape[:2]# 将图片转换为numpy数组,并进行形状变换,转化成3列data = img.reshape((-1, 3))# 将数据转换为浮点型data = np.float32(data)# 创建一个与数据长度相等的全零数组labels = np.zeros((height * width))# 随机选择k个点作为初始簇心cluster_centers_random = np.random.choice(height * width, k, replace = False)cluster_centers = data[cluster_centers_random, :]# 初始化距离数组distance = [ [] for i in range(k)]# 迭代k次for i in range(iter):print("第%d次迭代开始"% (i + 1))# 计算每个数据点到簇心的距离for j in range(k):distance[j] = np.sqrt(np.sum(np.square(data - cluster_centers[j]), axis = 1))# 根据距离最小的簇心标记每个数据点的类别labels = np.argmin(np.array(distance), axis = 0)# 更新簇心为每个簇内数据点的均值for j in range(k):cluster_centers[j] = np.mean(data[labels == j], axis = 0)# 判断图像是否为灰度图像if len(img.shape) == 2:# 重构聚类结果图像img_result = labels.reshape((height, width))else:# 将簇心转换为整型centers = np.uint8(cluster_centers)# 根据簇心和标签得到聚类结果res = centers[labels.flatten()]# 重构聚类结果图像img_result = res.reshape((img.shape))print("K-means聚类完成\n")return img_result

通过调用上述代码,解决问题二,问题二的解决代码如下:

import cv2
import matplotlib.pyplot as plt
from Methods import *def question2_Otsu():# 读取图像img = cv2.imread(r"D:\Image\img1.jpg")# 将彩色图像转为灰度图像img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 使用Otsu算法进行图像二值化img_otsu = Otsu(img_gray)# 复制img_otsu图像,进行反二值化img_otsu_inv = img_otsu.copy()# 反二值化img_otsu_inv = 255 - img_otsu# 绘制原始图像、灰度图像、二值化图像、反向二值化图像plt.subplot(2, 2, 1), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title('Original img'), plt.axis('off')plt.subplot(2, 2, 2), plt.imshow(img_gray, cmap = 'gray'), plt.title('Gray img'), plt.axis('off')plt.subplot(2, 2, 3), plt.imshow(img_otsu, cmap = 'gray'), plt.title('Binary img'), plt.axis('off')plt.subplot(2, 2, 4), plt.imshow(img_otsu_inv, cmap = 'gray'), plt.title('Inverse binary img'), plt.axis('off')# 调整图像布局并显示图像plt.tight_layout()plt.show()def question2_Clustering_Gray():# 读取图片img = cv2.imread(r"D:\Image\img1.jpg", 0)# 循环遍历k值for k in range(1, 10):# 显示原始图像if k == 1:plt.subplot(3, 3, k), plt.imshow(img, cmap = 'gray'), plt.title("Original img"), plt.axis('off')else:# 对图像进行kmeans聚类img_kmeans_gray = Kmeans(img, k, 50)# 显示聚类后的图像plt.subplot(3, 3, k), plt.imshow(img_kmeans_gray, cmap = 'gray'), plt.title(f'Kmeans img (k={k})'), plt.axis('off')# 调整图像布局并显示图像plt.tight_layout()plt.show()def question2_Clustering_color():# 读取图像img = cv2.imread(r"D:\Image\img1.jpg")# 不同的K值列表K_list = [1, 2, 4, 8, 16, 32]# 遍历不同的K值for i in range(len(K_list)):# 第一个K值特殊处理if i == 0:# 显示原始图片plt.subplot(2, 3, i + 1), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title("Original img"), plt.axis('off')else:# 执行Kmeans聚类,并显示聚类后的图像img_kmeans = Kmeans(img, K_list[i], 50)plt.subplot(2, 3, i + 1), plt.imshow(cv2.cvtColor(img_kmeans, cv2.COLOR_BGR2RGB)), plt.title(f"Kmeans img (k={K_list[i]})"), plt.axis('off')# 调整图像布局并显示图像plt.tight_layout()plt.show()# 执行相应函数
question2_Otsu()
question2_Clustering_Gray()
question2_Clustering_color()

代码的运行效果如下: 

 基于Otsu原理的灰度图分割:

基于kmeans原理的灰度图和彩色图分割:

上述就是使用OpenCV库解决问题一,根据算法原理编写代码文件解决问题二。

都看到最后了,不点个赞吗?


http://www.ppmy.cn/news/1373726.html

相关文章

事务(transaction)

事务&#xff0c;什么是事务&#xff0c;事务就是由单独单元的一个或多个sql语句组成&#xff0c;在这个单元中&#xff0c;每个sql语句都是相互依赖的。而整个单独单元是作为一个不可分割的整体存在&#xff0c;类似于物理当中的原子&#xff08;一种不可分割的最小单位&#…

Node.js和浏览器在JavaScript运行环境方面存在一些区别和联系

Node.js和浏览器在JavaScript运行环境方面确实存在一些区别和联系。 首先&#xff0c;让我们理解一下Node.js和浏览器的运行环境。Node.js是一个基于Chrome的V8引擎的服务器端JavaScript运行环境&#xff0c;允许开发者在服务器端运行JavaScript代码&#xff0c;并且提供了一系…

【MATLAB源码-第158期】基于matlab的海马优化算法(SHO)无人机三维路径规划,输出做短路径图和适应度曲线

操作环境&#xff1a; MATLAB 2022a 1、算法描述 海马优化器&#xff08;Sea Horse Optimizer, SHO&#xff09;是一种近年来提出的新型启发式算法&#xff0c;其设计灵感来源于海洋中海马的行为模式&#xff0c;特别是它们在寻找食物和伴侣时表现出的独特策略。海马因其独特…

【IC设计】Scala、Chisel、Chiseltest版本兼容信息

在maven仓库中精心整理的Scala、Chisel、Chiseltest的版本兼容信息&#xff0c;有了这个再也不怕sbt构建时找不到库文件了&#xff01; 目前百度上我搜不到这个资料&#xff0c;是我从maven官网上整理的&#xff0c;如果对你有用希望点点赞~ scala 2.11系列兼容的chisel版本为兼…

LabVIEW管道缺陷智能检测系统

LabVIEW管道缺陷智能检测系统 管道作为一种重要的输送手段&#xff0c;其安全运行状态对生产生活至关重要。然而&#xff0c;随着时间的推移和环境的影响&#xff0c;管道可能会出现老化、锈蚀、裂缝等多种缺陷&#xff0c;这些缺陷若不及时发现和处理&#xff0c;将严重威胁到…

【C++精简版回顾】14.(重载2)流重载

1.流重载 istream ostream 1.class class MM {friend ostream& operator<<(ostream& out, MM& mm);friend istream& operator>>(istream& in, MM& mm); public:MM() {}MM(int age,string name):age(age),name(name) {} private:int age;st…

Java的堆如何分代的?

前言&#xff1a; java对象一般都是朝生夕死&#xff0c;也有部分对象是一直存在的。两种对象如何都放在一起&#xff0c;进行垃圾回收的时候效率较低。所以通过将不同时期的对象放在不同的内存池中&#xff0c;节省垃圾回收的时间&#xff0c;提高性能。 组成&#xff1a; 新生…

Java的数据类型与变量详解

数据类型与变量 文章目录 数据类型与变量前言一、数据类型1. 基本数据类型2. 引用数据类型 二、包装类型1. 包装类型简介2. 自动装箱与拆箱3. 包装类型的常用方法4. 注意事项5. 示例 三、变量1. 变量声明2. 变量赋值3. 变量声明与赋值同时进行4. 示例 四、总结 前言 在Java编程…