Opencv基础入门笔记02

Opencv入门基础笔记02:矩阵的掩模操作

我们都知道,图片是由一个个像素点组成的,那么,我理解为一个巨大的矩阵,而矩阵掩模,就是,自己定义了一个特定的矩阵“kernel”或者叫“mask”,即掩模,然后,进行对矩阵的叉乘,是卷积滤波的一种体现,然后使图片呈现自己想要的样子。
实际上,掩膜mask是一种图像滤镜的模板,实用掩膜经常处理的是遥感图像。当提取道路或者河流,或者房屋时,通过一个n*n的矩阵来对图像进行像素过滤,然后将我们需要的地物或者标志突出显示出来。这个矩阵就是一种掩膜。在OpenCV中,掩模操作是相对简单的。大致的意思是,通过一个掩模矩阵,重新计算图像中的每一个像素值。掩模矩阵控制了旧图像当前位置以及周围位置像素对新图像当前位置像素值的影响力度。用数学术语讲,即我们自定义一个权重表。

1.用到的主要函数(filter2D,Mat,saturate_cast)
我们主要将掩模操作实现图片对比度的提高。用到的掩模为

Mat kern = (Mat_<char>(3,3) <<  0, -1,  0,
                               -1,  5, -1,
                                0, -1,  0);

对应实际的数学计算公式为
I(i,j) = 5*I(i,j) - [I(i-1,j) + I(i+1,j) + I(i,j-1) + I(i,j+1)]
其中(i,j)是图片像素点坐标,I就是我们上面说的Kernel或者叫掩模mask。这里是3*3的矩阵掩模,计算后得到的值赋给矩阵掩模的中心锚点anchor(这里就是kernel中5对应的图片像素下的坐标)
接下来讲saturate_cast函数
这是像素范围处理saturate_cast()
saturate_cast(-100),返回0
saturate_cast(288),返回255
saturate_cast(100),返回100
图片的像素值通常一般在0–255之间,这个函数的功能就是确保RGB值范围在0~255之间。因为进行图片的滤波或者掩模,用公式计算得到的像素值可能会**>255或者<0**,所以必须用这个函数保证。当然,也可以自己用代码实现这个函数。
函数调用filter2D功能
filter2D 函数的定义如下:

void filter2D( InputArray src, OutputArray dst, int ddepth,
                            InputArray kernel, Point anchor=Point(-1,-1),
                            double delta=0, int borderType=BORDER_DEFAULT );

其中src与dst是Mat类型变,ddepth是图片深度,delta是计算公式里面的一个系数,一般0。后面的参数borderType是边缘填充类型,用默认值。
函数作用是实现图片自定义卷积滤波,掩模操作属于滤波范围,所以可以用,不同的kernel能使图片实现不同的效果上面定义的kernel就是用于实现图片对比度的提高的

当然这个函数也是可以通过对图片像素指针的获取以及像素指针的操作进行源代码复现。

2.代码过程
我将用C++与python实现上述的图片矩阵掩模操作,以及用C++语言实现saturate_cast函数及简单实现filter2D
first,C++实现掩模操作

int main() {
	//1.读取图片
	src_image = imread("E:\\360downloads\\kernel.jpg");
	//2.判断图片是否读入
	if (!src_image.data) {
		printf("can't load image ,please checkout your path!");
		return 0;
	}

	//定义掩模mask(kernel)
	Mat kernel = (Mat_<char>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);//3*3的卷积核,注意是char型

	//调用filter2D函数实现图片矩阵掩模操作 
	filter2D(src_image, dst_image, -1, kernel, Point(-1, -1));
	
	//显示
	imshow("src", src_image);
	imshow("dst", dst_image);
	

	waitKey(0);
	return 0;
}

在这里插入图片描述
python实现上述功能

import cv2 as cv
import numpy as np

# 1.读取图片
src_image = cv.imread("E:\\360downloads\\img.jpg")
# 2.判断图片是否读入
if src_image is None:
    print("can't load image ,please checkout your path!")
    exit(0)
# 3.python没有Mat,用numpy定义掩模kernel(mask)
kernel = np.array(([0, -1, 0],
                   [-1, 5, -1],
                   [0, -1, 0]), dtype="float32")
# 4.调用filter2D实现图片矩阵掩模操作
dst_image = cv.filter2D(src_image, -1, kernel)

# 5.显示
cv.imshow("src", src_image)
cv.imshow("dst", dst_image)
cv.waitKey(0)

在这里插入图片描述3.用C++实现filter2D函数图片对比度提高

int main() {
	//1.读取图片
	src_image = imread("E:\\360downloads\\kernel.jpg");
	//2.判断图片是否读入
	if (!src_image.data) {
		printf("can't load image ,please checkout your path!");
		return 0;
	}
	Mat dst_image= Mat::zeros(src_image.size(),src_image.type());
	//定义掩模mask(kernel)
	//Mat kernel = (Mat_<char>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);//3*3的卷积核

	//调用filter2D函数实现图片矩阵掩模操作 
	//filter2D(src_image, dst_image, -1, kernel, Point(-1, -1));
	
	
	//首先先获取图片的高度,宽度,通道数
	int col = (src_image.cols - 1)*src_image.channels();
	int row = src_image.rows;
	int channel = src_image.channels();
	//遍历像素点
	for (int i = 1; i < row - 1; i++)
	{
		//定义一个指针变量来获取要用到的当前行,上一行,下一行的像素指针
		const uchar* src_current = src_image.ptr<uchar>(i);
		const uchar* src_back = src_image.ptr<uchar>(i - 1);
		const uchar* src_next = src_image.ptr<uchar>(i + 1);
		//定义一个指针变量获取目标图片的当前行的像素指针;
		uchar* dst_pixel = dst_image.ptr<uchar>(i);
		for (int j = channel; j < col; j++)
		{
			//运用公式对单个像素操作;
			dst_pixel[j] = saturate_cast<uchar>(5 * src_current[j] - (src_current[j + channel] +
				src_current[j - channel] + src_next[j] + src_back[j]));


		}
	}

	
	//显示
	imshow("src", src_image);
	imshow("dst", dst_image);
	

	waitKey(0);
	return 0;
}

在这里插入图片描述
未完,笔记先复习到现在,待查。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨夜※繁华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值