opencv之kmeans原理与分割实例

2023-10-26

opencv之K-Means原理与实现方法(C++和python版本)

KMeans原理

今天记录一下opencv中kmeans中的原理以及图像分割的一个实例,K-Means是对数据进行分类的算法,属于无监督学习的一种。
首先需要确定对图像进行类别的数目确定,即需要知道几个类别,然后每个类别都有一个中心点

然后根据距离来决定每个数据点属于哪个类别标签,一次循环实现对所有数据点分类之后,直到指定的循环次数或者前后两次的delta小于指定阈值,停止计算得到最终的样本数据的标签。

先讲讲opencv中KMeans数据分类的函数:
OpenCV中KMeans数据分类的API为:

KMeans函数

double cv::kmeans(
	InputArray data,
	int K,
	InputOutputArray bestLabels,
	TermCriteria criteria,
	int attempts,
	int flags,
	OutputArray centers = noArray() 
)

data是输入的样本数据,必须是按行组织样本,每一行为一个样本数据,列表示样本的维度
K表示最终的分类数目
bestLabels 表示最终分类每个样本的标签(每个样本都有一个标签)
criteria 表示KMeans分割的停止条件
attempts 表示采样不同初始化标签尝试次数
flag表示中心初始化方法(有以下三种方法)

  • KMEANS_RANDOM_CENTERS
  • KMEANS_PP_CENTERS
  • KMEANS_USE_INITIAL_LABELS
    centers表示最终分割以后的每个cluster的中心位置

在这里插入图片描述
Kmeans数据分类演示,左图是数据坐标,可以理解为直方图,可以看出他是两个大类,而右图中黄色的是类的中心点

下面使用贾志刚老师的代码进行一个演示,先看python版本的

代码演示

1.python版本

导入必须的库

import numpy as np
import cv2
from matplotlib import pyplot as plt

初始化为25行两列,X范围是25-50的范围,Y的取值范围是60-85。

X = np.random.randint(25,50,(25,2))
Y = np.random.randint(60,85,(25,2))
pts = np.vstack((X,Y))
# 初始化数据
data = np.float32(pts)#必须是一个浮点数数据
print(data.shape)

生成的X
在这里插入图片描述
生成的Y

在这里插入图片描述
pts = np.vstack((X,Y))会将其两组数据叠加在一起

定义停止条件

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)#计算10次,且差值小于1.0时停止计算
ret,label,center=cv2.kmeans(data,2,None,criteria,2,cv2.KMEANS_RANDOM_CENTERS)
print(len(label))
print(center)

获取不同标签的点,标签为0或者1

A = data[label.ravel()==0]
B = data[label.ravel()==1]

最后绘制图片

plt.scatter(A[:,0],A[:,1])
plt.scatter(B[:,0],B[:,1],c = 'r')
plt.scatter(center[:,0],center[:,1],s = 80,c = 'y', marker = 's')
plt.xlabel('Height'),plt.ylabel('Weight')
plt.show()

在这里插入图片描述
分类的结果如图所示

2.C++版本

相当于python版本,C++版本写起来区别会大很多,下面开始吧

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
	Mat img(500, 500, CV_8UC3);
	RNG rng(12345);

	Scalar colorTab[] = {
		Scalar(0, 0, 255),
		Scalar(255, 0, 0),
	};
int numCluster = 2;
	int sampleCount = rng.uniform(5, 500);
	Mat points(sampleCount, 1, CV_32FC2);

	// 生成随机数
	for (int k = 0; k < numCluster; k++) {
		Point center;
		center.x = rng.uniform(0, img.cols);
		center.y = rng.uniform(0, img.rows);
		Mat pointChunk = points.rowRange(k*sampleCount / numCluster,
			k == numCluster - 1 ? sampleCount : (k + 1)*sampleCount / numCluster);
		rng.fill(pointChunk, RNG::NORMAL, Scalar(center.x, center.y), Scalar(img.cols*0.05, img.rows*0.05));
	}
	randShuffle(points, 1, &rng);
// 使用KMeans
	Mat labels;
	Mat centers;
	kmeans(points, numCluster, labels, TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1), 3, KMEANS_PP_CENTERS, centers);
	//points输入的样本数据,必须是按行组织样本,每一行为一个样本数据,列表示样本的维度;k表示最终的分类数目
	//bestlabels表示最终分类每个样本的标签,criteria表示kmeans分割的停止条件 attempts表示采样不同初始化标签尝试次数,一般与K等值
	//flag表示中心初始化方法,centers表示最终分割以后的每个cluster的中心位置
	

	// 用不同颜色显示分类
	img = Scalar::all(255);
	for (int i = 0; i < sampleCount; i++) {
		int index = labels.at<int>(i);
		Point p = points.at<Point2f>(i);
		circle(img, p, 2, colorTab[index], -1, 8);
	}

	// 每个聚类的中心来绘制圆
	for (int i = 0; i < centers.rows; i++) {
		int x = centers.at<float>(i, 0);
		int y = centers.at<float>(i, 1);
		printf("c.x= %d, c.y=%d", x, y);
		circle(img, Point(x, y), 40, colorTab[i], 1, LINE_AA);
	}

	imshow("KMeans-Data-Demo", img);
	waitKey(100000);
	return 0;
}

在这里插入图片描述
相对于python,C++的演示效果可能不是那么理想,的确还是pytho的数据分析能力更强更简便啊

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv之kmeans原理与分割实例 的相关文章

  • 将代码从 openCV 更新到 openCV2

    我正在尝试将 python 中的一些代码从 openCV 更新为 openCV2 原代码如下 self capture cv CaptureFromCAM 0 cv SetCaptureProperty self capture cv CV
  • 使用 Python (OpenCV) 中的霍夫线变换从模拟时钟读取时间

    我一直在尝试编写一个程序 在图片上找到钟面 然后继续从中读取时间 定位效果相当好 但阅读时间 不是那么多 cv2 HoughLines 函数返回线条所在的角度 从图像顶部开始测量 以及它们与图像左上角的距离 经过一些调整后 我成功地说服我的
  • 即使 CMake 中的 WITH_CUDA=ON,OpenCV 也不会使用 CUDA 进行构建

    我尝试使用 CMake GUI 版本 构建 OpenCV 3 1 以启用 Cuda 我已经安装了 Cuda 7 5 64 位版本 CMake 自动找到了 Cuda 工具包的正确路径 我确保WITH CUDA值设置为ON 并按下配置 这是我对
  • 如何在 OpenCV 中绘制图像的 3D 直方图

    更新 我找到更多例子 我现在可以做到 我可以在 3d 中绘制多个直方图吗 https stackoverflow com questions 35210337 can i plot several histograms in 3d 我知道这
  • 查找图像列表的中值

    如果我有一个由 3D ndarray 表示的图像列表 例如 x y color 我可以使用哪些操作来输出具有所有值中值的图像 我正在使用 for 循环 发现它太慢了 这是我使用的矢量化实现NumPy http www numpy org 在
  • 裁剪图像后,如何找到新的边界框坐标?

    这是我得到的收据图像 我使用 matplotlib 绘制了它 x1 y1 x2 y2 x3 y3 x4 y4 bbox coords 650 850 1040 850 1040 930 650 930 image cv2 imread IM
  • 是否可以使用 opencv 将旋转图像复制到另一个图像的旋转矩形 ROI 中?

    好吧 很抱歉再次问几乎相同的问题 但我已经尝试了很多方法 但我仍然无法做我想做的事情 我什至不确定单独使用 opencv 是否可行 我旋转了一个图像 我想将其复制到另一个图像中 问题是 无论我以何种方式裁剪这个旋转图像 它总是复制到第二个图
  • 分割车牌字符

    我在从车牌图像中分割字符时遇到问题 我应用了以下方法来提取车牌字符 车牌图像的自适应阈值 选择具有特定纵横比的轮廓 如果车牌图像中有任何阴影 如附件中所示 由于二值化不正确 我无法正确分割字符 图像中的阴影合并图像中的相邻字符 我已经对具有
  • 如何在Python中的二值图像上使用kmeans聚类?

    我试图对两个不同的人采取二元面具 其他一切都是黑色的 现在我想使用将每个人分组到他们自己的集群中K means这样我最终就可以在它们周围绘制边界框 这是我到目前为止的代码 def kmeans img k values range 1 5
  • OpenCV 中的随机顺序洗牌 cv::Mat

    里面没有函数吗OpenCV随机打乱矩阵 按行排序 Input 1 2 3 4 5 6 7 8 9 Output 4 5 6 7 8 9 1 2 3 cv randShuffle 函数似乎只是对整个数组中的元素进行随机排序 我正在使用较新的
  • 改进 cvFindChessboardCorners

    不幸的是 我无法找到我的问题的任何解决方案 我想做的是使用 OpenCV 方法改进结果cvFindChessboardCorners为了能够实现更好的相机校准 因为我认为这就是为什么我在不扭曲 校正图像时得到较差结果的原因 就像我之前的问题
  • pytesseract 无法按预期识别文本?

    我正在尝试通过 opencv 和 pytesseract 运行一个简单的车牌图像来获取文本 但我无法从中获取任何内容 按照此处的教程进行操作 https Circuitdigest com microcontroller projects
  • 图像中土壤颗粒分水岭以外的替代分割技术

    我正在寻找一种替代方法来分割以下土壤颗粒图像中的颗粒 而不是Python中的分水岭分割 因为它可能会误导对颗粒的正确检测 此外 我正在研究边缘检测图像 使用HED算法 作为附加 我希望找到一种更好的方法来分割颗粒以进行进一步处理 因为我想获
  • OpenCV的calcOpticalFlowPyrLK抛出异常

    一段时间以来 我一直在尝试使用 OpenCV 构建一个小型光流示例 除了函数调用 calcOpticalFlowPyrLK 之外 一切正常 该函数在控制台窗口中打印以下失败的断言 OpenCV错误 断言失败 mytype typ0 CV M
  • 如何在Python中删除图像的背景

    我有一个包含全角人类图像的数据集 我想删除这些图像中的所有背景 只留下全角人物 我的问题 有没有Python代码可以做到这一点 我是否需要每次都指定人员对象的坐标 这是使用 Python OpenCV 的一种方法 读取输入 转换为灰色 阈值
  • C++/OpenCV - 用于视频稳定的卡尔曼滤波器

    我尝试使用卡尔曼滤波器稳定视频以进行平滑 但我有一些问题 每次 我都有两帧 一帧是当前帧 另一帧是当前帧 这是我的工作流程 计算 goodFeaturesToTrack 使用 calcOpticalFlowPyrLK 计算光流 只保留优点
  • 在白色背景上将透明 PNG 保存为 JPEG

    假设我有一张 BGRA 图像numpy数组看起来非常像这样 233 228 230 128 233 228 230 128 233 228 230 0 164 160 159 65 199 197 196 65 255 255 254 12
  • 使用高斯混合模型进行皮肤检测

    我正在根据以下进行皮肤检测算法本文 http www cc gatech edu rehg Papers SkinDetect IJCV lowres pdf 第 21 页有两个模型 高斯皮肤混合模型和非皮肤颜色模型 第一个皮肤检测模型效果
  • Android Camera2 API - 实时显示处理后的帧

    我正在尝试创建一个实时处理相机图像并将其显示在屏幕上的应用程序 我正在使用camera2 API 我创建了一个本机库来使用 OpenCV 处理图像 到目前为止 我已经成功设置了一个 ImageReader 来接收 YUV 420 888 格
  • 尝试导入 cv2(opencv-python) 包时出错

    我正在尝试使用 cv2 opencv python 包访问我的网络摄像头 当我尝试导入它时 出现此错误 Traceback most recent call last File server py line 6 in

随机推荐

  • c语言 水仙花数

    水仙花数是指一个N位正整数 N 3 它的每个位上的数字的N次幂之和等于它本身 本题要求编写程序 计算所有N位水仙花数 输入格式 输入在一行中给出一个正整数N 3 N 7 输出格式 按递增顺序输出所有N位水仙花数 每个数字占一行 输入样例 3
  • mysql数据库设置远程连接权限,执行grant all privileges on *.* to 'root'@'%' identified by '密码' with grant optio报错

    mysql数据库设置远程连接权限 执行grant all privileges on to root identified by 密码 with grant optio报错 ERROR 1558 HY000 Column count of
  • 华为OD机试 - 字符个数统计(C++ & Java & JS & Python)

    目录 描述 输入描述 输出描述 示例1 示例2 C python Java 描述 编写一个函数 计算字符
  • linux AIO (异步IO) 那点事儿

    在高性能的服务器编程中 IO 模型理所当然的是重中之重 需要谨慎选型的 对于网络套接字 我们可以采用epoll 的方式来轮询 尽管epoll也有一些缺陷 但总体来说还是很高效的 尤其来大量套接字的场景下 但对于Regular File 来说
  • 机器学习中的方差与偏差

    方差与偏差的定义 方差 不同的训练数据集训练出的模型输出值之间的差异 偏差 用所有可能的训练数据集训练出的所有模型的输出的平均值与真实模型的输出值之间的差异 方差与偏差的数学公式 首先 以回归为例 模型的期望预测指针对不同数据集D 模型对样
  • (三)STM32基础——GPIO介绍

    目录 GPIO简介 GPIO基本结构 GPIO位结构 输入部分 输出部分 推挽输出模式 开漏输出 编辑 开漏复用输出 编辑 八种输入输出模式 浮空 上拉 下拉输入 编辑 模拟输入 开漏 推挽输出 复用开漏 复用推挽输出 GPIO寄存器 GP
  • 【Spark ML】第 3 章:监督学习

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 【论文精读】The Missing Link: Finding label relations across datasets

    一 背景 概要 和之前其他论文工作不同的是 论文的主要目的是探究不同数据集间标签的关系 而不是将其合并 论文中提到的关系是identity parent child overlap 为了探究这些关系 提出了几种方法 基于language 基
  • 一文实现:在python中调用matlab程序,保姆级安装windows环境下的matlab.engine教程

    一 前言 我最近在做一个基于图像融合的目标检测工程 我经常用matlab去研究和创新新型的图像融合算法 因为matlab有着python所不可比拟的数据可视化功能和大量的滤波分解框架包 在目标检测等涉及到神经网络的程序编写上 python又
  • 机器学习

    学习目标 了解什么是EM算法 知道极大似然估计 知道EM算法实现流程 一 初识EM算法 EM算法也称期望最大化 Expectation Maximum 简称EM 算法 它是一个基础算法 是很多机器学习领域算法的基础 比如隐式马尔科夫算法 H
  • 2、TCP、多进程并发、多线程并发(linux网络编程)

    三次握手和四次挥手的过程都是在内核实现的 三次握手 通信的时候不再需要SYN标识位了 只有在请求连接的时候需要SYN标识位 传输数据的时候的随机序号seq就是最近一次对方发送给自己的ACK的随机序号值 而发给对方的ACK就是上次刚刚发给对方
  • JDK安装配置教程

    JDK简介 Java Development Kit JDK 是 Sun 公司 已被 Oracle 收购 针对 Java 开发员的软件开发工具包 自从 Java 推出以来 JDK 已经成为使用最广泛的 Java SDK Software d
  • Windows10下安装Git

    Git是一个开源的分布式版本控制系统 可以有效 高速的处理从很小到非常大的项目版本管理 具体安装步骤如下 第一步 先从官网下载最新版本的Git 官网地址 https git scm com downloads 点击上图中表示的地方进行下载
  • 如何修改安卓系统为自己的云服务器,安卓手机改装云服务器

    安卓手机改装云服务器 内容精选 换一换 本节操作介绍华为云上云服务器的跨账号跨区域迁移 建议采用镜像迁移方式 服务器迁移的常见场景与常用的迁移方式请参考迁移的背景知识 跨账号跨区域迁移的方法请参考方案介绍常见的服务器迁移场景包括物理服务器与
  • 【论文精读】Grounded Language-Image Pre-training(GLIP)

    一 背景 https arxiv org abs 2112 03857 https github com microsoft GLIP 这篇论文做的任务是phrase grounding 属于visual grounding的一种 phra
  • MySQL 修改默认值

    alter TABLE tableName alter COLUMN columnName set default defaultValue
  • 电阻式湿度传感器原理

    电阻式湿度传感器是利用湿敏元件的电气特性 如电阻值 随湿度的变化而变化的原理进行湿度测量的传感器 湿敏元件一般是在绝缘物上浸渍吸湿性物质 或者通过蒸发 涂覆等工艺制各一层金属 半导体 高分子薄膜和粉末状颗粒而制作的 在湿敏元件的吸湿和脱湿过
  • 大模型应用落地实践:2大路径、3大痛点、5大革命、6大预判!

    省时查报告 专业 及时 全面的行研报告库 省时查方案 专业 及时 全面的营销策划方案库 免费下载 2023年8月份全网热门报告合集 ChatGPT提词示例 让你的ChatGPT聪明100倍 超百页干货资料 AI应用的难点 痛点与未来 202
  • 双端队列,以顺序表实现双端队列,在队头和队尾添加删除元素

    include
  • opencv之kmeans原理与分割实例

    opencv之K Means原理与实现方法 C 和python版本 KMeans原理 今天记录一下opencv中kmeans中的原理以及图像分割的一个实例 K Means是对数据进行分类的算法 属于无监督学习的一种 首先需要确定对图像进行类