初探opencv——利用矩阵掩膜操作提高对比度

今天开始更新opencv的学习。

笔者的开发环境选在vs2017+opencv3.2。

何为矩阵的掩膜操作?其实就是选定一部分我们自己感兴趣的区域,在这个区域内对像素进行操作,利用掩膜我们可以重新计算每个像素的像素值。
比如矩阵A:
(1) 0 − 1 0 − 1 5 − 1 0 − 1 0 \begin{matrix} 0 & -1 & 0 \\ -1 & 5 & -1 \\ 0 & -1& 0 \end{matrix} \tag{1} 010151010(1)

这就是一个掩膜,若中间元素为A[i, j],它指的操作就是
A [ i , j ] = 5 ∗ A [ i , j ] − A [ i , j − 1 ] − A [ i , j + 1 ] − A [ i + 1 , j ] − A [ i − 1 , j ] A[i , j] = 5 * A[i , j] - A[i , j-1] - A[i , j+1] - A[i+1 , j] - A[i-1 , j] A[i,j]=5A[i,j]A[i,j1]A[i,j+1]A[i+1,j]A[i1,j]
通过该掩膜我们可以增强图片的对比度。


主要方法:
1.获取图片指针:src.ptr<uchar>(row)[col] 指的是获取Mat对象src的row行col列的像素值,类型定义为uchar,返回值为指针。获取了指针之后就可以对图像像素进行运算。

2.saturate_cast方法是为了令运算后的像素值合法,即位于0-255之间。

#include <opencv2\opencv.hpp>
#include <iostream>
#include <math.h>
// 矩阵的掩膜操作  提高对比度
using namespace cv;

int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("E:/opencv_testImages/0.jpg");
	if (!src.data) {
		printf("could not find...\n");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);
//	printf("%d\n%d\n%d", src.channels(), src.cols, src.rows);
	int cols = (src.cols-1) * src.channels();
	int offsetx = src.channels(); // 通道数 为3
	int rows = src.rows;
	double t = getTickCount();
	dst = Mat::zeros(src.size(), src.type()); // 初始化

	for (int row = 1; row < (rows - 1); row++) {
		// 获取指针
		const uchar* previous = src.ptr<uchar>(row - 1); //上一行
		const uchar* current = src.ptr<uchar>(row);  //当前行
		const uchar* next = src.ptr<uchar>(row + 1);  //下一行
		uchar* output = dst.ptr<uchar>(row);  // output的指针  赋值给它
		for (int col = offsetx; col < cols; col++) {
			// 左右偏移多少由通道数目决定
			output[col] = saturate_cast<uchar>(5 * current[col] - ( current[col - offsetx] + current[col + offsetx] + previous[col] + next[col] ));
			// saturate_cast函数为了令rgb值合法(0-255)
		}
	}

	namedWindow("constrast image demo", CV_WINDOW_AUTOSIZE);
	imshow("constrast image demo", dst);

	double timeconsume = (getTickCount() - t) / getTickFrequency(); //显示运行了多久
	printf("tim consume %.2f", timeconsume);

	waitKey(0);
	return 0;
}

更简单的方法——利用api:
我们可以直接定义一个kernel,交给filter2D函数自动运算,得出来的结果是一样的。

// 定义一个三行三列的矩阵
Mat kernel = (Mat_<float>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(src, dst, -1, kernel);
imshow("out2", dst);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wangbowj123

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

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

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

打赏作者

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

抵扣说明:

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

余额充值