opencv_c++学习(二十四)

news2024/11/27 17:42:02

一、积分图像

在这里插入图片描述
积分图像是对原图像进行积分操作的算法。如上图左所示,不同颜色代表不同区域。当我们想求取一个像素点的积分值时,我们需要求取该点左上方区域的数据之和,如P0的积分值是浅蓝色区域的数据之和。 P1的积分值为蓝色和橙色区域的数值之和。
在这里插入图片描述
上图展示的是倾斜求和积分方式。
积分图像计算函数:

integral(InputArray src, OutputArray sum, OutputArray sqsum, OutputArray tilted, int sdepth = -1, int sqdepth = -1)

src:输入图像,图像数据类型可以是CV_8U、CV_32F或者CV_64F。
sum:输出标准求和积分图像,图像的数据类型可以是CV_32S、CV_32F或者CV_64F。
sqsum:输出平方求和积分图像,图像的数据类型可以是CV_32F或者CV_64F。
tilted:输出倾斜45°的倾斜求和积分图像,其数据类型与sum相同。
sdepth:输出标准求和积分图像和倾斜求和积分图像的数据类型标志,可以选择的参数为CV_32S,CV_32F或者CV_64F,参数默认值为-1,表示满足数据存储的自适应类型。
sqdepth:输出平方求和积分图像的数据类型标志,可以选择的参数为CV_32F或者CV_64F,参数默认值为-1,表示满足数据存储的自适应类型。
本节使用案例如下:

int main() {
	//创建16*16的全1矩阵
	Mat img = Mat::ones(16, 16, CV_32FC1);

	//在图像中加入随机噪声
	RNG rng(10000);

	for (int y = 0; y < img.rows; y++)
	{
		for (int x = 0; x < img.cols; x++)
		{
			float d = rng.uniform(-0.5, 0.5);
			img.at<float>(y, x) = img.at<float>(y, x) + d;
		}
	}

	//计算标准求和积分
	Mat sum;
	integral(img, sum);

	//为了便于显示,转成CV_8U格式
	Mat sum8U = Mat_<uchar>(sum);
	namedWindow("q", WINDOW_NORMAL);
	imshow("q", sum8U);

	//计算平方求和积分
	Mat sqsum;
	integral(img, sum, sqsum);

	//为了便于显示,转成CV_8U格式
	Mat sqsum8U = Mat_<uchar>(sqsum);
	namedWindow("w", WINDOW_NORMAL);
	imshow("w", sqsum8U);

	//计算倾斜求和积分
	Mat tilted;
	integral(img, sum, sqsum, tilted);

	//为了便于显示,转成CV_8U格式
	Mat tilted8U = Mat_<uchar>(tilted);
	namedWindow("e", WINDOW_NORMAL);
	imshow("e", tilted8U);
		 
	waitKey(0);
	return 0;
}

二、图像分割——漫水填充

在这里插入图片描述

floodFill(InputOutputArray image, InputOutputArray mask, Point seedPoint, Scalar newVal, Rect * rect = 0, Scalar loDiff = Scalar(), upDiff =, Scalar scalar(), int flags = 4

image:输入输出图像,图像数据类型可以为CV_8U或者CV_32F的单通道或者三通道图像。
mask:掩码矩阵,尺寸比如输入图像的宽和高各大2的单通道图像,用于标记漫水填充的区域。
seedPoint:种子点。
newVal:归入种子点区域内像素点的新像素值。
rect:种子点漫水填充区域的最小矩形边界,默认值为0,表示不输出边界。loDiff:添加进种子点区域条件的下界差值。
upDiff:添加进种子点区域条件的上界差值。
flags:漫水填充方法的操作标志。
本节应用案例如下:

int main() {

	//读取图片
	Mat src = imread("1.png");
	if (src.empty())
	{
		printf("不能打开空图片");
		return -1;
	}

	//在生成随机像素的随机数
	RNG rng(10000);

	//连同邻域方式
	int connectivity = 4;

	//掩码图像数值
	int maskVal = 255;

	//漫水填充的标志位,不改变种子像素值
	int flags = connectivity | (maskVal << 8) | FLOODFILL_FIXED_RANGE;

	//设置与选中像素点的差值,上下都为20
	Scalar loDiff = Scalar(20, 20, 20);
	Scalar upDiff = Scalar(20, 20, 20);

	//声明掩膜矩阵变量
	Mat mask = Mat::zeros(src.rows + 2, src.cols + 2, CV_8UC1);

	while (true)
	{
		//随机产生图像中某一像素点
		int py = rng.uniform(0, src.rows - 1);
		int px = rng.uniform(0, src.cols - 1);
		Point point = Point(px, py);

		//对彩色图像填充像素值
		Scalar newVal = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));

		//进行漫水填充,返回填充像素数目
		int area = floodFill(src, mask, point, newVal, &Rect(), loDiff, upDiff, flags);

		imshow("q", mask);

		//按ESC键退出程序
		char key = (char)waitKey();
		if (key == 27 || key == 'q' || key == 'Q')
		{
			break;
		}

	}
	waitKey(0);
	return 0;

}

三、图像分割方法——分水岭法

在这里插入图片描述

watershed(InputArray image, InputOutputArray markers)

image:输入图像,数据类型为CV_8U的三通道图像。
markers:输入(种子区域)/输出CV_32S的单通道图像的标记结果,与原图像具有相同的尺寸。
本节样例如下:

int main() {

	//读取要标记的图片
	Mat src = imread("1.png");
	//读取原始图片
	Mat src1 = imread("3.png");
	if (src.empty() || src1.empty())
	{
		printf("不能打开空图片");
		return -1;
	}

	//watershed参数设置
	Mat maskWaterShed;

	//转化为灰度图
	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);

	Mat imgMask;
	//二值化并开运算
	threshold(gray, imgMask, 254, 255, THRESH_BINARY);
	Mat k = getStructuringElement(0, Size(3, 3));
	morphologyEx(imgMask, imgMask, MORPH_OPEN, k);

	//轮廓提取
	vector<vector<Point>>contours;
	vector<Vec4i> hierarchy;
	findContours(imgMask, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);

	//在maskWaterShed上绘制轮廓,用于输入分水岭算法
	maskWaterShed = Mat::zeros(imgMask.size(), CV_32S);
	for (int index = 0; index < contours.size(); index++)
	{
		drawContours(maskWaterShed, contours, index, Scalar::all(index + 1), -1, 8, hierarchy, INT_MAX);
	}

	//进行分水岭算法
	watershed(src1, maskWaterShed);

	//随机生成颜色,用于显示分割
	vector<Vec3b> colors;
	for (int i = 0; i < contours.size(); i++)
	{
		int b = theRNG().uniform(0, 255);
		int g = theRNG().uniform(0, 255);
		int r = theRNG().uniform(0, 255);
		colors.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
	}

	//显示图像
	Mat resultImg = Mat(src1.size(), CV_8UC3);
	for (int i = 0; i < imgMask.rows; i++)
	{
		for (int j = 0; j < imgMask.cols; j++)
		{
			//绘制不同区域
			int index = maskWaterShed.at<int>(i, j);

			//如果区域边界
			if (index == -1)
			{
				resultImg.at<Vec3b>(i, j) = Vec3b(255, 255, 255);
			}

			//没有被标记的区域置0
			else if (index<=0 || index > contours.size())
			{
				resultImg.at<Vec3b>(i, j) = Vec3b(0, 0, 0);
			}

			//其他区域保持像素不变
			else
			{
				resultImg.at<Vec3b>(i, j) = colors[index - 1];
			}
		}
	}

	imshow("resultImg", resultImg);
	resultImg = resultImg * 0.8 + src1 * 0.2;
	imshow("resultImg1", resultImg);

	//绘制每个区域的图案
	for (int n = 0; n < contours.size(); n++)
	{
		Mat resImage1 = Mat(src.size(), CV_8UC3);
		for (int i = 0; i < imgMask.rows; i++)
		{
			for (int j = 0; j < imgMask.cols; j++)
			{
				//绘制不同区域
				int index = maskWaterShed.at<int>(i, j);

				//如果区域边界
				if (index == n)
				{
					resultImg.at<Vec3b>(i, j) = src1.at<Vec3b>(i, j);
				}

				else
					resultImg.at<Vec3b>(i, j) = Vec3b(0, 0, 0);

			}
		}
		imshow(to_string(n), resImage1);
	}
	waitKey(0);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/573186.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSM框架学习-SSM整合(整合配置、功能模块开发、接口测试)

1. 整合配置 首先创建maven模块&#xff0c;导入相应的坐标 <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.10.RELEASE</version></dependency&g…

计算机是如何工作的??(多进程编程)

目录 多进程编程进程调度组织进程调度 本篇博客的重点知识是进程进程的调度 操作系统&#xff1a;像是windows&#xff0c;android&#xff0c;iOS等都是常见的操作系统 下面是关于计算机在底层工作的原理流程图 在操作系统层面&#xff1a; 对上&#xff0c;要给软件提供稳…

《低代码指南》——低代码维格云能源行业解决方案

目录 典型场景介绍: 一、能源资产管理 二、碳核查 三、配电运营 总 结: 从业界实际情况来看,流程建设本身是一个对业务现实进行抽象的过程,这个过程即使不考虑软件开发的门槛,对于很多客户而言也是个涉及较长周期的复杂工作,往往需要咨询专家或专业公司帮助其建设内…

【Python】函数式编程例子

知识目录 一、写在前面&#x1f37a;二、七段数码管显示倒计时✨三、斐波那契序列&#x1f37a;四、总结撒花&#x1f60a; 一、写在前面&#x1f37a; 大家好&#xff01;我是初心&#xff0c;今天我们回到了Python从入门到精通。 今天跟大家分享的文章是 Python中函数的使用…

sentinel原理分析及源码剖析

sentinel功能 sentinel功能可参考官网 可以从sentinel的dashboard中了解到sentinel的核心功能包括 流控规则 阈值类型&#xff1a;QPS、并发线程数流控模式&#xff1a;直接&#xff0c;关联&#xff0c;链路流控效果&#xff1a;快速失败&#xff08;滑动时间窗算法Default…

分享Python采集99个焦点图,总有一款适合您

分享Python采集99个焦点图&#xff0c;总有一款适合您 Python采集的99个焦点图下载链接&#xff1a;https://pan.baidu.com/s/1887LXr2ovCAw-Bp7PuM66g?pwdbyx4 提取码&#xff1a;byx4 原创Jquery焦点图片切换效果 自定义大小&#xff0c;使用方 jquery立体式缩略图焦点图…

Linux系统之编译安装python3

Linux系统之编译安装python3 一、python3介绍1. python3简介2. python3特点 二、检查本地环境1. 检查本地操作系统版本2. 检查内核版本3. 检查当前python版本 三、安装前准备工作四、下载python最新版本源码包1. 访问python官网2. 创建下载目录3. 下载python源码包4. 解压pytho…

Git业务实践记录

您好&#xff0c;如果喜欢我的文章&#xff0c;可以关注我的公众号「量子前端」&#xff0c;将不定期关注推送前端好文~ 场景描述 最近在开发一个新的功能&#xff0c;和往常一样先建了一个分支进行开发&#xff0c;开发到周期60%的时候&#xff0c;后端临时通知需要将大功能…

思维导图到底有多少种?

思维导图是一种非常实用的工具&#xff0c;它可以帮助我们更好地组织和表达我们的思想。在日常生活和工作中&#xff0c;我们可以使用各种不同类型的思维导图来解决不同的问题。下面&#xff0c;我将介绍一些常见的思维导图类型以及如何使用ProcessOn思维导图软件制作思维导图。…

前端学习--Vue(5)

一、动态组件 动态切换组件的显示与隐藏 1.1 <component>组件 <!-- component是vue内置的标签占位符 is中规定标签名 --><component :is"comName"></component> 动态组件在被展示的时候被创建&#xff0c;隐藏的时候被销毁 如果想要组件…

Day1:Windows消息循环机制

先区分几个概念 系统&#xff1a;特指Windwos操作系统 应用程序&#xff1a;指一个程序&#xff0c;比如QQ&#xff0c;微信等 窗口&#xff1a;每个应用程序都 可以拥有窗口&#xff0c;而且可以有多个&#xff0c;但一般会有一个主窗口。 消息&#xff1a;window系统定义…

【系统集成项目管理工程师】计算题专题二

七、进度网络计算题 1、单代号网络图 六标时图 正推取大&#xff08;红色&#xff09;&#xff1b;反推取小&#xff08;绿色&#xff09; 关键路径&#xff1a;ACDE&#xff08;关键路径下的活动总浮动时间都是 0&#xff09; 浮动时间&#xff08;总时长&#xff09;&…

《Spring Guides系列学习》guide31 - guide34 及中期简单回顾

要想全面快速学习Spring的内容&#xff0c;最好的方法肯定是先去Spring官网去查阅文档&#xff0c;在Spring官网中找到了适合新手了解的官网Guides&#xff0c;一共68篇&#xff0c;打算全部过一遍&#xff0c;能尽量全面的了解Spring框架的每个特性和功能。 接着上篇看过的gu…

Scrum敏捷迭代规划和执行

Sprint Backlog看板 迭代工作的开展是围绕Sprint Backlog展开的&#xff0c;在Leangoo中&#xff0c;我们需要为每个迭代创建一个Sprint Backlog看板。Sprint Backlog&#xff08;迭代&#xff09;看板&#xff0c;用于管理当前Sprint的需求和开发任务&#xff0c;可视化展示每…

Cesium教程(七):加载自定义影像数据

GIS开发中经常需要调用本地或供应方发布的影像数据,加载独立的场景,此时可以借助GeoServer发 布自定义影像数据。 geoserver下载地址:geoserver下载 1、geoserver安装 1.1 安装方式1(推荐) 要求已安装tomcat:下载 Web Archive 版本的GeoServer,下载完毕解压,目 录如…

【JavaSE】Java基础语法(十九):接口新特性

文章目录 1. 接口组成更新概述2. 接口中默认方法3. 接口中静态方法4. 接口中私有方法 1. 接口组成更新概述 常量&#xff1a;接口可以定义全局常量&#xff0c;使用关键字public static final修饰。 抽象方法&#xff1a;接口中可以定义抽象方法&#xff0c;使用关键字public…

零基础如何入门网络安全?2023年专业学习路线看这篇就够了

前景 很多零基础朋友开始将网络安全作为发展的大方向&#xff0c;的确&#xff0c;现如今网络安全已经成为了一个新的就业风口&#xff0c;不仅大学里开设相关学科&#xff0c;连市场上也开始大量招人。 那么网络安全到底前景如何&#xff1f;大致从市场规模、政策扶持、就业…

汽车以太网通道和相关组件的测试

随着车载网络的发展&#xff0c;已经出现了CAN、LIN、FlexRay、MOST等成熟的协议&#xff0c;而基于LVDS/USB技术的链路传输模式也得到了广泛的应用。然而&#xff0c;面对不断提高的摄像头、显示器和不同传感器系统共享的更复杂信息分辨率&#xff0c;就需要更高的传输速度。 …

企业内容管理入门指南:从概念到实践,提升协作效率和质量

在现代企业管理中&#xff0c;存在一种容易被忽视但又极为重要的管理理念——企业内容管理。由于“企业内容”这一概念过于抽象&#xff0c;大家对它可能还比较模糊。所以&#xff0c;今天我们来聊聊企业内容管理。 在开始之前&#xff0c;对企业内容做一个简明的介绍&#x…

API对接是什么意思,技术分享

在计算机科学中&#xff0c;应用程序接口&#xff08;API&#xff09;是一种程序编程接口&#xff0c;定义了应用程序之间或应用程序和操作系统之间的通信方式。API对接就是在不同的应用程序之间实现数据交换和信息传输的过程。当两个不同的应用程序需要共享数据时&#xff0c;…