C++OpenCV(4):图像截取与掩膜操作

news2024/11/24 20:14:55

🔆 文章首发于我的个人博客:欢迎大佬们来逛逛
🔆 OpenCV项目地址及源代码:点击这里


文章目录

  • 图像截取
  • 图像掩膜操作

图像截取

ROI操作,指的是:region of interest,感兴趣区域。

我们可以对一张图片的某个感兴趣的部分进行截取然后操作,这个截取的过程叫做**ROI**操作。

通过三种方法实现ROI操作:

  • Rect选定范围
Rect::Rect(int x, int y, int width, int height);
/*******************************************************************
*			x: 					左上角x坐标
*			y:					左上角y坐标
*			width:				宽度
*			height:				 高度
*********************************************************************/
Mat roi= img(Rect(x, y, w, h));
  • Range选定范围
Range::Range(int _start, int _end) ;
/*******************************************************************
*			_start: 			 起点
*			_end:				 终点	
*********************************************************************/
Mat roi= img(Range(x,xx),Range(y,yy));
  • selectROI 专用API选择感兴趣区域,
Rect selectROI(InputArray img, bool showCrosshair = true, bool fromCenter = false);
/*******************************************************************
*			img: 					原图
*			showCrosshair:			鼠标选框,是否显示十字线
*			fromCenter:				是否以起始鼠标位置为中心
*********************************************************************/
//Rect rect= selectROI(img, false, false);
//1.显示img
//2.鼠标选择区域
//3.使用“空格”或“enter”来完成当前选择并开始一个新的选择,使用“esc”终止多个ROI选择过程  
void selectROIs(const String& windowName, InputArray img,CV_OUT std::vector<Rect>& boundingBoxes, bool showCrosshair = true, bool fromCenter = false);

案例代码:

其中具有一个selectROIs的版本,可以让我们选择多个区域。

选择一个区域后按下回车,即可保存这个部分到一个std::vector<Rect>& 中,因此最终的全部选择的区域都在这个Rect的容器中。

其中我们选择好区域后,在使用Mat重载的() 运算符即可做到在这张图片中截取一部分:

原型如下:

Mat operator()( Range rowRange, Range colRange ) const;
Mat operator()( const Rect& roi ) const
#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>
#include <map>

class testROI {
public:
	testROI() :mt(cv::imread("dog.png")) {}
	void show(const std::string& title = "原图") {
		for (auto& x : save) {
			cv::imshow(x.first, x.second);
		}
		cv::waitKey(0);
	}
	void testRect(int x = 50, int y = 0, int w = 200, int h = 200) {
		save["rect"] = mt(cv::Rect(x, y, w, h));
	}
	void testRange(int x = 50, int y = 0, int w = 200, int h = 200) {
		save["range"] = mt(cv::Range(x, x + h), cv::Range(y, y + w));
	}
	void testSelect() {
		save["select"] = mt(cv::selectROI(mt,false,false));
	}
	void testSelect2(const std::string& windowName) {
		std::vector<cv::Rect> mts;
		cv::selectROIs(windowName, mt, mts, false, false);
		char name = 'a';
		for (auto& x : mts) {
			save[std::to_string(name)] = mt(x);
			name += 1;
		}
	}
private:
	cv::Mat mt;
	std::map<std::string, cv::Mat> save;
};

int main() {
	testROI* roi = new testROI();
	//roi->testRange();
	//roi->testRect();
	//roi->testSelect();
	cv::namedWindow("dog");
	roi->testSelect2("dog");
	roi->show();

	return 0;
}

在这里插入图片描述


图像掩膜操作

掩膜操作指的是:用一个矩阵和原图像进行卷积运算,重新计算像素值。

因此我们需要定义一个权重表:

  • 掩膜矩阵
  • 计算公式

掩膜操作可以提高图像的对比度,对比度提高可以增加图像感官度、锐化,让看起来有点模糊的图像更清晰。

使用以下公式可以提高图像的对比度:

F ( i , j ) = 5 ∗ F ( i , j ) − F ( i − 1 , j ) − F ( i + 1 , j ) − F ( i , j − 1 ) − F ( i , j + 1 ) F(i,j) = 5*F(i,j)-F(i-1,j)-F(i+1,j)-F(i,j-1)-F(i,j+1) F(i,j)=5F(i,j)F(i1,j)F(i+1,j)F(i,j1)F(i,j+1)

对于这个公式的掩膜矩阵可以表示成如下的形式:

在这里插入图片描述

因此我们在定义掩膜矩阵的时候就可以使用这个。

我们通过两种方式实现图片的掩膜操作:

  • filter2D实现

    • 我们使用Mat_来创建一个指定为3*3的掩膜矩阵,并且完成赋值
    • 接着使用 filter2D来实现操作。
    //定义掩膜矩阵
    Mat dst;
    Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
    filter2D(img, dst, img.depth(), kernel);
    /*******************************************************************
    *			img: 					原图
    *			dst:					存储结果图
    *			img.depth():			原图深度
    *			kernel:				 	 掩膜矩阵
    *********************************************************************/
    
  • 像素点实现,即对每个像素点执行上面的公式计算

完整代码实现:

  • testFilter2D 使用 filter2D完成掩膜计算。
  • testPixel 使用像素点完成掩膜计算。
#include <iostream>
#include <opencv2/opencv.hpp>
#include <map>

class Mask {
public:
	Mask()
		:mt(cv::imread("dog.png")) {
		saves["origin"] = mt;
	}
	void testFilter2D() {
		//API
		cv::Mat kernel = (cv::Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
		cv::filter2D(mt, saves["mask"], mt.depth(), kernel);
	}
	void testPixel() {
		saves["pixel"] = cv::Mat::zeros(mt.size(), mt.type());
		int dims = mt.channels();
		int rows = mt.rows - 1;
		int cols = (mt.cols - 1) * dims;
		for (int i = 1; i < rows ; i++) {
			uchar* pre = mt.ptr<uchar>(i - 1);	//ptr获取某一行,pre指前一行
			uchar* next = mt.ptr<uchar>(i + 1);	//next指下一行
			uchar* cur = mt.ptr<uchar>(i);		//cur是当前行
			uchar* output = saves["pixel"].ptr<uchar>(i); //对当前行操作
			for (int j = dims; j < cols; j++) {		//
				output[j] = cv::saturate_cast<uchar>(5 * cur[j] - pre[j] - next[j] - cur[j - dims] - cur[j + dims]);
			}	
		}
	}
	void show() {
		for (auto& x : saves) {
			cv::imshow(x.first, x.second);
		}
		cv::waitKey(0);
	}

private:
	cv::Mat mt;
	std::map<std::string, cv::Mat> saves;
};
int main()
{
	Mask* pmask = new Mask();
	pmask->testFilter2D();
	pmask->testPixel();
	pmask->show();

	
	return 0;
}

在这里插入图片描述


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

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

相关文章

Vue 项目增加版本号输出, 可用于验证是否更新成功

webpack 1. vue.config.js 中增加以下配置, 此处以增加一个日期时间字符串为例, 具体内容可以根据自己需求自定义 // vue.config.js module.exports {chainWebpack(config) {config.plugin(define).tap(args > {args[0][process.env].APP_VERSION ${JSON.stringify(new …

行为型模式--模版方法模式(图文详解)

模版方法模式--图文详解 采摘机器人-场景体验模版方法模式-解决问题模版方法模式-定义优缺点优点缺点 采摘机器人-场景体验 今天看抖音上外国开始使用采摘苹果的机器人&#xff0c;我们模仿一下的他的大体流程&#xff1a; 主体采摘车进入苹果园进入苹果指定采摘地点&#xf…

通过自动化单元测试的形式守护系统架构

目录 0前言 1 背景 2 为什么选择 Archunit 3 Archunit 是什么 4 引入 Archunit 4.1 开始就是如此简单 4.2 如何组织架构规则 4.3 团队如何规范化 0前言 通过自动化单元测试的形式守护系统架构是一种有效的方式&#xff0c;可以确保系统在不断演进和修改的过程中保持稳…

Python实战之数据挖掘详解

一、Python数据挖掘 1.1 数据挖掘是什么&#xff1f; 数据挖掘是从大量的、不完全的、有噪声的、模糊的、随机的实际应用数据中&#xff0c;通过算法&#xff0c;找出其中的规律、知识、信息的过程。Python作为一门广泛应用的编程语言&#xff0c;拥有丰富的数据挖掘库&#…

数据分享|R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病...

全文链接&#xff1a;http://tecdat.cn/?p23061 这个数据集&#xff08;查看文末了解数据免费获取方式&#xff09;可以追溯到1988年&#xff0c;由四个数据库组成。克利夫兰、匈牙利、瑞士和长滩。"目标 "字段是指病人是否有心脏病。它的数值为整数&#xff0c;0无…

盖子的c++小课堂——第二十讲:动态规划

前言 中间呢其实还有两讲&#xff0c;但是那两讲太easy了&#xff0c;根本难不倒你们&#xff0c;所以&#xff0c;我索性不放了~~那我们今天讲一个比较容易的知识点——动态规划&#xff08;终于没人给我催更了&#xff01;哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈…

IOC控制反转--.net framework

IOC控制反转–.net framework 分层架构&#xff1a; 一、传统依赖倒置实现 传统工艺&#xff1a;会有依赖&#xff0c;上端全部展示细节 BaseBll baseBll new BaseBll(); baseBll.DoSomething();依赖于抽象&#xff1a;左边依赖倒置&#xff0c;面向抽象 实现类继承接口&am…

React18和React16合成事件原理(附图)

&#x1f4a1; React18合成事件的处理原理 “绝对不是”给当前元素基于addEventListener做的事件绑定&#xff0c;React中的合成事件&#xff0c;都是基于“事件委托”处理的&#xff01; 在React17及以后版本&#xff0c;都是委托给#root这个容器&#xff08;捕获和冒泡都做了…

动态规划入门第1课

1、从计数到选择 ---- 递推与DP&#xff08;动态规划&#xff09; 2、从递归到记忆 ---- 子问题与去重复运算 3、动态规划的要点 第1题 网格路1(grid1) 小x住在左下角(0,0)处&#xff0c;小y在右上角(n,n)处。小x需要通过一段网格路才能到小y家。每次&#xff0c;小x可以选…

视频基础知识

1.视频比特率 视频的比特率是指传输过程中单位时间传输的数据量。可以理解为视频的编码采样率。单位是kbps&#xff0c;即每秒千比特。视频比特率是决定视频清晰度的一个重要指标。比特率越高&#xff0c;视频越清晰&#xff0c;但数据量也会越大。比如一部100分钟的电影&#…

5.4 Bootstrap 下拉菜单(Dropdown)插件

文章目录 Bootstrap 下拉菜单&#xff08;Dropdown&#xff09;插件用法在导航栏内在标签页内 选项方法 Bootstrap 下拉菜单&#xff08;Dropdown&#xff09;插件 Bootstrap 下拉菜单 这一章讲解了下拉菜单&#xff0c;但是没有涉及到交互部分&#xff0c;本章将具体讲解下拉菜…

(链表) 剑指 Offer 58 - I. 翻转单词顺序 ——【Leetcode每日一题】

❓剑指 Offer 06. 从尾到头打印链表 难度&#xff1a;简单 输入一个链表的头节点&#xff0c;从尾到头反过来返回每个节点的值&#xff08;用数组返回&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,3,2] 输出&#xff1a;[2,3,1] 限制&#xff1a; 0 < 链…

自己实现数据结构,有更好的可操作性

https://leetcode.cn/problems/asteroid-collision/ 就是说&#xff0c;非得用人家写的栈不可么 stl 的 stack&#xff0c;没办法随机访问&#xff0c;用 vector 或者再不济数组&#xff0c;就好了&#xff0c;非要用 stl 的&#xff0c;就导致还得有另一个 vector 维护向左走…

多目标灰狼算法(MOGWO)的Matlab代码详细注释及难点解释(佳点集改进初始种群的MOGWO)

目录 一、外部种群Archive机制 二、领导者选择机制 三、多目标灰狼算法运行步骤 四、MOGWO的Matlab部分代码详细注释 五、MOGWO算法难点解释 5.1 网格与膨胀因子 5.2 轮盘赌方法选择每个超立方体概率 为了将灰狼算法应用于多目标优化问题,在灰狼算法中引入外部种群Archi…

Spring MVC -- 返回数据(静态页面+非静态页面+JSON对象+请求转发与请求重定向)

目录 1. 返回静态页面 2. 返回非静态页面 2.1 ResponseBody 返回页面内容 2.2 RestController ResponseBody Controller 2.3 示例:实现简单计算的功能 3. 返回JSON对象 3.1 实现登录功能&#xff0c;返回 JSON 对象 4. 请求转发(forward)或请求重定向(redirect) 4.1 请…

Day 63 : 集成学习之 AdaBoosting (1. 带权数据集)

63.1 AdaBoosting基本算法&#xff1a;先从初始训练集训练一个弱学习器&#xff0c;在根据弱学习器的表现对训练样本进行权重调整&#xff0c;经过若干轮之后&#xff0c;将得到一组分类器&#xff0c;将数据输入这组分类器后会得到一个综合且准确的的分类结果。“三个臭皮匠&a…

评论管理功能

后端 bp.get("/comment/list") def comment_list():comments CommentModel.query.order_by(CommentModel.create_time.desc()).all()comment_list []for comment in comments:comment_dict comment.to_dict()comment_list.append(comment_dict)return restful.ok…

Python模块requests基本用法

简介 Python 的 requests 模块是一个流行的第三方库&#xff0c;用于发送HTTP请求。它提供了一组简洁且易于使用的API&#xff0c;使得在Python中进行网络通信变得更加简单和灵活。 目录 1. 基本概念 1.1. HTTP 协议 1.2. GET 请求 1.3. POST 请求 1.4. get 和 post 的区别…

uniapp 小程序 评分组件

效果图&#xff1a; 1、组件&#xff1a;starsRating.vue <template><view class"stars"><image click"btnStars1" class"starsicon" :src"starsObject[0]" mode"widthFix"></image><image c…

Stream API将对象中的某一字段取出转换为list或数组

List<DevicePartMaintain> devicePartMaintainList devicePartMaintainMapper.selectDevicePartMaintainByMitId(mitId);所有id转换为List 要使用Stream流获取devicePartMaintainList中所有的id&#xff0c;您可以使用stream()方法将列表转换为流&#xff0c;然后使用…