【OpenCV学习| (02) 图像处理 | 矩阵的掩膜操作

本文详细介绍了如何利用掩膜操作进行图像对比度调整,包括获取图像像素指针、使用saturate_cast确保RGB值范围,以及利用filter2D函数应用掩膜。文中还提供了C++代码示例,演示了掩膜操作的具体实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.掩膜操作

在这里插入图片描述
掩膜操作实现图像对比度调整红色是中心像素,从上到下,从左到右对每个像素做同样的处理操作,得到最终结果就是对比度提高之后的输出图像Mat对象

1.1 获取图像像素指针

CV_Assert(myImage.depth() == CV_8U);
Mat.ptr(int i=0) 获取像素矩阵的指针,索引i表示第几行,从0开始计行数。
获得当前行指针const uchar* current= myImage.ptr(row );
获取当前像素点P(row, col)的像素值 p(row, col) =current[col]

1.2. 像素范围处理saturate_cast

saturate_cast(-100),返回 0。
saturate_cast(288),返回255
saturate_cast(100),返回100
这个函数的功能是确保RGB值得范围在0~255之间

2. 函数调用filter2D功能

定义掩膜:Mat kernel = (Mat_(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D( src, dst, src.depth(), kernel );其中src与dst是Mat类型变量、src.depth表示位图深度,有32、24、8等。
在这里插入图片描述

代码示例:

在这里插入图片描述

  • channels():
    Mat矩阵元素拥有的通道数。例如常见的RGB彩色图像,channels3;而灰度图像只有一个灰度分量信息, - channels1。
    表示的是一个矩阵中的每个元素分别有几个值,如一个4*3的矩阵,有12个元素,每个元素如果有三个值,则此矩阵有三个通道。如果每个元素有四个值,则此矩阵有四个通道。

原文链接:https://blog.youkuaiyun.com/cv_walking/article/details/78315662

说明:
CV_Assert(image.depth() == CV_8U);

#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ )
#define CV_8S   1
/ASSERT()是一个调试程序时经常使用的宏,
//在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。
//如果表达式不为0,则继续执行后面的语句

assert 的作用是:

现计算表达式 expression ,如果其值为假(即为 0),那么它先向 stderr 打印一条出错信息,然后通过调用 abort 来终止程序运行。请看下面的程序清单:

#include <stdio.h> 
#include <assert.h> 
#include <stdlib.h> 
int main( void ) {
 FILE *fp;
fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同 名文件 
assert( fp ); 
fclose( fp ); //所以这里不会出错
 
fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打 开文件失败 
assert( fp );
 fclose( fp ); 
return 0; } //所以这里出错 //程序永远都执行不到这里来

使用 assert()的缺点是:

频繁的调用会极大的影响程序的性能,增加额外的开 销。在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用 assert 调用.

示例代码如下:

#include <stdio.h> #define NDEBUG #include <assert.h>

如果想创建一个跟图片宽和高相同的图片,可以使用.create方法

C++: void Mat::create(int rows, int cols, int type)


C++: void Mat::create(Size size, int type)
C++: void Mat::create(int ndims, const int* sizes, int type)
Parameters: 
ndims – New array dimensionality.
rows – New number of rows.
cols – New number of columns.
size – Alternative new matrix size specification: Size(cols, rows)
sizes – Array of integers specifying a new array shape.
type – New matrix type.

测试程序:

SrcImage.create(SrcImage2.rows, SrcImage2.cols, CV_8UC3);

如果想创建一个矩形框或者矩形

查看官方文档可以知道

template<typename _Tp>
cv::Rect_< _Tp >::Rect_	(_Tp 	_x,_Tp 	_y,
_Tp 	_width,
_Tp 	_height 
)		

因此,创建一个矩形框或者矩形是一定要当心,注意是以宽和高来定义,与前面的创建窗口使用的行和列有所不同。

测试程序:

#include <opencv2/core/core.hpp>  
#include<opencv2/highgui/highgui.hpp>  
#include"opencv2/imgproc/imgproc.hpp"  
#include <iostream>  
 
using namespace cv;
 
void test()
{
	Mat SrcImage;
	//Mat GrayImage;
	//Mat BinaryImage;
	//const int IMAGE_WIDTH = 400;
	//const int IMAGE_HEIGHT = 200;
 
	//对比图像
	Mat SrcImage2;
	SrcImage2 = imread("400.jpg");
	std::cout <<"行:"<< SrcImage2.rows << std::endl;
	std::cout <<"列:"<< SrcImage2.cols << std::endl;
 
	//创建图像
	/*SrcImage.create(IMAGE_HEIGHT, IMAGE_WIDTH, CV_8UC3);*/
	SrcImage.create(SrcImage2.rows, SrcImage2.cols, CV_8UC3);
	//填充成白色
	rectangle(SrcImage, Rect(0, 0, SrcImage2.cols/2, SrcImage2.rows/2), CV_RGB(0, 0, 0), CV_FILLED);
	namedWindow("原图");
	imshow("原图", SrcImage);
 
}
void main()
{
	test();
	waitKey();
}

示列:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
	Mat src, dst;
	src = imread("test.jpg");
	if (src.empty())
	{
		printf("could not find image...");
	}
	CV_Assert(src.depth() == CV_8U);
	namedWindow("maskImage",CV_WINDOW_AUTOSIZE);
	imshow("maskImage", src);
	
	/*
	Mat resultImage;
	image.copyTo(resultImage);

	int he = image.cols;
	int height = image.row;
	int nchannel = image.channels;
	*/
	Mat M;
	M.create(4,3,CV_8UC2);
	M = Scalar(127,127);
	cout << "M=" << endl << "" << M << endl;
	uchar* fistrow = M.ptr<uchar>(0);
	printf("%d\n", *fistrow);
	
	Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	cout << "C= " << endl << C << "" << endl;

	waitKey(0);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值