Opencv计算机视觉编程攻略-第二节 图像像素操作

news2025/3/28 22:39:41

第二节 图像像素操作

  • 1.访问像素值
  • 2.用指针扫描图像
  • 3.扫描图像并访问相邻像素
  • 4.实现简单的图像运算
  • 5.图像重映射

1.访问像素值

以椒盐噪声为例展示像素值访问的几种方法

void salt(cv::Mat image, int n) {

	// C++11 random number generator
	std::default_random_engine generator;
	std::uniform_int_distribution<int> randomRow(0, image.rows - 1);
	std::uniform_int_distribution<int> randomCol(0, image.cols - 1);
	
	// use image with a Mat_ template 使用模板操作做转换后可直接访问
	cv::Mat_<uchar> img(image);

	int i,j;
	for (int k=0; k<n; k++) {

		// random image coordinate
		i= randomCol(generator);
		j= randomRow(generator);

        // 自适应通道数
		if (image.type() == CV_8UC1) { // gray-level image

			// single-channel 8-bit image
			image.at<uchar>(j,i)= 255; 

		} else if (image.type() == CV_8UC3) { // color image

			// 3-channel image
			image.at<cv::Vec3b>(j,i)[0]= 255; 
			image.at<cv::Vec3b>(j,i)[1]= 255; 
			image.at<cv::Vec3b>(j,i)[2]= 255; 
			// 直接使用位置访问 下列为单通道赋值
			img(j,i)= 255; 

			// or simply:
			// image.at<cv::Vec3b>(j, i) = cv::Vec3b(255, 255, 255);
		}
	}
}

2.用指针扫描图像

以处理图像像素为例展示指针扫描图像,使用指针并结合位运算的速度远高于逐个计算,double duration = (cv::getTickCount() - start) / cv::getTickFrequency()使用该语句实现算法是耗时分析:

void colorReduceIO(const cv::Mat &image, // input image
	               cv::Mat &result,      // output image
	               int div = 64) {

	int nl = image.rows; // number of lines
	int nc = image.cols; // number of columns
	int nchannels = image.channels(); // number of channels

	// allocate output image if necessary
	result.create(image.rows, image.cols, image.type());
    //1.指针扫描处理
	for (int j = 0; j<nl; j++) {
		// get the addresses of input and output row j
		// 每一行的开头地址
		const uchar* data_in = image.ptr<uchar>(j);
		uchar* data_out = result.ptr<uchar>(j);
		// 在opencv中按照BGR-BGR逐个排列
		for (int i = 0; i<nc*nchannels; i++) {
			// process each pixel ---------------------
			data_out[i] = data_in[i] / div*div + div / 2;
			// end of pixel processing ----------------
		} // end of line
	}
	//2.图像实现运算符重载
	 int n= static_cast<int>(log(static_cast<double>(div))/log(2.0) + 0.5);
      // mask used to round the pixel value
      uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
      // perform color reduction
      image=(image&cv::Scalar(mask,mask,mask))+cv::Scalar(div/2,div/2,div/2);
     //3. 整图对象遍历
      cv::MatIterator_<cv::Vec3b> it= image.begin<cv::Vec3b>();
      cv::MatIterator_<cv::Vec3b> itend= image.end<cv::Vec3b>();
      const cv::Vec3b offset(div/2,div/2,div/2);
      for ( ; it!= itend; ++it) {
        // process each pixel ---------------------
        *it= *it/div*div+offset;
        // end of pixel processing ----------------
      }
}

3.扫描图像并访问相邻像素

在图像运算中,时长需要访问周边位置的像素,比如边缘提取、边缘锐化,以边缘锐化为例,展示如何访问相邻像素:

void sharpen2D(const cv::Mat &image, cv::Mat &result) {

	// 1. 直接使用filter2D进行卷积计算
	cv::Mat kernel(3,3,CV_32F,cv::Scalar(0));
	// assigns kernel values
	kernel.at<float>(1,1)= 5.0;
	kernel.at<float>(0,1)= -1.0;
	kernel.at<float>(2,1)= -1.0;
	kernel.at<float>(1,0)= -1.0;
	kernel.at<float>(1,2)= -1.0;
	//filter the image
	cv::filter2D(image,result,image.depth(),kernel);
	//2.通过指针实现高效运算
	result.create(image.size(), image.type()); // allocate if necessary
	int nchannels= image.channels();

	for (int j= 1; j<image.rows-1; j++) { // for all rows (except first and last)

		const uchar* previous= image.ptr<const uchar>(j-1); // previous row
		const uchar* current= image.ptr<const uchar>(j);	// current row
		const uchar* next= image.ptr<const uchar>(j+1);		// next row

		uchar* output= result.ptr<uchar>(j);	// output row

		for (int i=nchannels; i<(image.cols-1)*nchannels; i++) {

			// apply sharpening operator
			*output++= cv::saturate_cast<uchar>(5*current[i]-current[i-nchannels]-current[i+nchannels]-previous[i]-next[i]); 
		}
	}

	// Set the unprocess pixels to 0 屏蔽边缘像素
	result.row(0).setTo(cv::Scalar(0));
	result.row(result.rows-1).setTo(cv::Scalar(0));
	result.col(0).setTo(cv::Scalar(0));
	result.col(result.cols-1).setTo(cv::Scalar(0));
}

4.实现简单的图像运算

Mat进行实现图像的一些简单操作:

	cv::addWeighted(image1,0.7,image2,0.9,0.,result);
	// using overloaded operator
	result= 0.7*image1+0.9*image2;
	//两种操作等效

5.图像重映射

在日常处理中,诸如投影变换,重采样,等等变换中,需要根据对应像素坐标位置计算目标位置,可通过重映射来快速实现:
void wave(const cv::Mat &image, cv::Mat &result) {

	// the map functions
	cv::Mat srcX(image.rows,image.cols,CV_32F); // x-map
	cv::Mat srcY(image.rows,image.cols,CV_32F); // y-map

	// creating the mapping
	for (int i=0; i<image.rows; i++) {
		for (int j=0; j<image.cols; j++) {
		    //使用指针会更加高效 这里没有
			srcX.at<float>(i,j)= j;
			srcY.at<float>(i,j)= i+3*sin(j/6.0);
			// horizontal flipping
			// srcX.at<float>(i,j)= image.cols-j-1;
			// srcY.at<float>(i,j)= i;
		}
	}

	// applying the mapping 重映射函数
	cv::remap(image,  // source image
		      result, // destination image
			  srcX,   // x map
			  srcY,   // y map
			  cv::INTER_LINEAR); // interpolation method
}

该节相关代码已上传到个人文档,按需下载
链接: 点击下载

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

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

相关文章

华为交换相关

端口模式 &#xff08;1&#xff09;access&#xff1a;只能属于单个VLAN&#xff0c;一般用于连接计算机端口 &#xff08;2&#xff09;trunk&#xff1a;端口允许多个VLAN通过&#xff0c;可以接收和发送多个VLAN报文&#xff0c;默认情况下只有管理VLAN不携带标签信息 &…

Chrome Performance 面板完全指南:从卡顿到丝滑的终极调试术

1.写在前面 前端性能调试是优化网页加载速度和运行效率的关键步骤&#xff0c;Chrome DevTools 的 Performance 面板 是核心工具; 2.Performance 面板使用步骤 ★ 基础 打开面板 在 Chrome 中按 F12 → 切换到 Performance 标签页。 开始录制 方式一&#xff1a;点击 ⚫️ 圆…

JDK 24:Java 24 中的新功能

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;历代文学&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编程&#xff0c;高并发设计&#xf…

ubuntu服务器server版安装,ssh远程连接xmanager管理,改ip网络连接。图文教程

ventoy启动服务器版iso镜像&#xff0c;注意看server名称&#xff0c;跟之前desktop版ubuntu不一样。没有gui界面。好&#xff0c;进入命令行界面。语言彻底没汉化了&#xff0c;选英文吧&#xff0c;别的更看不懂。 跟桌面版ubuntu类似&#xff0c;选择是否精简系统&#xff0…

python机器学习——新手入门学习笔记

一&#xff0c;概论 1.什么是机器学习 定义&#xff1a; 机器学习是从数据中自动分析获得模型&#xff0c;并利用模型对未知数据进行预测。 其实就是通过问题和数据&#xff0c;发现规律&#xff0c;并进行预测&#xff0c;与人脑相似。目的就是从历史数据当中获得规律&#x…

LabVIEW 与 PLC 通讯的常见方式

在工业自动化和数据采集系统中&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09; 广泛用于控制和监测各种设备&#xff0c;而 LabVIEW 作为强大的图形化编程工具&#xff0c;常用于上位机数据处理和可视化。为了实现 LabVIEW 与 PLC 的高效通讯&#xff0c;常见的方法包…

深度学习 Deep Learning 第9章 卷积网络 CNN

深度学习 Deep Learning 第9章 卷积网络 章节概述 本章深入探讨了卷积网络的原理、变体及其在深度学习中的应用。卷积网络通过卷积操作实现了参数共享和稀疏连接&#xff0c;显著提高了模型的效率和性能。本章首先介绍了卷积操作的基本形式及其在不同数据维度上的应用&#x…

Tekton系列之实践篇-从触发到完成的完整执行过程

以下介绍的是基于 Gitee 仓库 的 Tekton 工作流程 操作流程 定义task 克隆代码的task # task-clone.yaml apiVersion: tekton.dev/v1beta1 kind: Task metadata:name: git-clone spec:workspaces:- name: source # 工作目录params:- name: repo-url # 你的 Gitee 仓库地址…

【简单学习】Prompt Engineering 提示词工程

一、Prompt 1、Prompt 是什么&#xff1f; Prompt 是一种人为构造的输入序列&#xff0c;用于引导 GPT 模型根据先前输入的内容生成相关的输出。简单来说&#xff0c;就是你向模型提供的 “提示词”。 在 ChatGpt 中&#xff0c;我们可以通过设计不同的 prompt&#xff0c;让…

零基础入门网络爬虫第5天:Scrapy框架

4周 Srapy爬虫框架 不是一个简单的函数功能库&#xff0c;而是一个爬虫框架 安装&#xff1a;pip install scrapy 检测&#xff1a;scrapy -h Scrapy爬虫框架结构 爬虫框架 爬虫框架是实现爬虫功能的一个软件结构和功能组件集合爬虫框架是一个半成品&#xff0c;能够帮助…

C#设计模式快速回顾

知识点来源&#xff1a;人间自有韬哥在&#xff0c;豆包 目录 一、七大原则1. 单一职责原则 (Single Responsibility Principle)2. 开放封闭原则 (Open-Closed Principle)3. 里氏替换原则 (Liskov Substitution Principle)4. 接口隔离原则 (Interface Segregation Principle)5…

分页查询互动问题(用户端)

文章目录 概要整体架构流程技术细节小结 概要 需求分析以及接口设计 技术细节 1.Controller层 GetMapping("/page")ApiOperation("分页查询问题")public PageDTO<QuestionVO> queryQuestionPage(QuestionPageQuery query){return questionService…

【全队项目】智能学术海报生成系统PosterGenius(项目介绍)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a;&#x1f3c0;大模型实战训练营_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…

【线程安全问题的原因和方法】【java形式】【图片详解】

在本章节中采用实例图片的方式&#xff0c;以一个学习者的姿态进行描述问题解决问题&#xff0c;更加清晰明了&#xff0c;以及过程中会发问的问题都会一一进行呈现 目录 线程安全演示线程不安全情况图片解释&#xff1a; 将上述代码进行修改【从并行转化成穿行的方式】不会出…

解决IDEA中maven找不到依赖项的问题

直接去官网找到对应的依赖项jar包&#xff0c;并且下载到本地&#xff0c;然后安装到本地厂库中。 Maven官网&#xff1a;https://mvnrepository.com/ 一、使用mvn install:install-file命令 Maven提供了install:install-file插件&#xff0c;用于手动将jar包安装到本地仓库…

pyside6的QGraphicsView体系,当鼠标位于不同的物体,显示不同的右键菜单

代码&#xff1a; # 设置样本图片的QGraphicsView模型 from PySide6.QtCore import Qt, QRectF, QObject from PySide6.QtGui import QPainter, QPen, QColor, QAction, QMouseEvent from PySide6.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsPixmapItem, QGra…

Python自动化测试 之 DrissionPage 的下载、安装、基本使用详解

Python自动化测试 之 DrissionPage 使用详解 &#x1f3e1;前言&#xff1a;一、☀️DrissionPage的基本概述二、 &#x1f5fa;️环境安装2.1 ✅️️运行环境2.2 ✅️️一键安装 三、&#x1f5fa;️快速入门3.1 页面类&#x1f6f0;️ChromiumPage&#x1f6eb; SessionPage&…

Java替换jar包中class文件

在更新java应用版本的运维工作中&#xff0c;由于一些原因&#xff0c;开发没办法给到完整的jar包&#xff0c;这个时候&#xff0c;就可以只将修改后的某个Java类的class文件替换掉原来iar包中的class文件&#xff0c;重新启动服务即可&#xff1a; 1、将jar包和将要替换的cl…

AI Tokenization

AI Tokenization 人工智能分词初步了解 类似现在这个&#xff0c;一格子 一格子&#xff0c;拼接出来的&#xff0c;一行或者一句&#xff0c;像不像&#xff0c;我们人类思考的时候组装出来的话&#xff0c;并用嘴说出来了呢。

关于大数据的基础知识(四)——大数据的意义与趋势

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于大数据的基础知识&#xff08;四&a…