图像像素的读写操作-4

一、代码部分

(1)头文件中声明函数

#pragma once
#include<opencv2/opencv.hpp>

using namespace cv;

class QuickDemo
{
public:
	void colorSpace_Demo(Mat& image);
	void mat_creation_demo(Mat& image);
	void pixel_visit_demo(Mat& image); // 此次声明的函数
};

  (2)quickdemo.cpp中添加函数

// 图像像素的读写操作
void QuickDemo::pixel_visit_demo(Mat& image)
{
	int width = image.cols;
	int height = image.rows;
	int dims = image.channels(); //灰度图dim为1,彩色图dim为3,图不同,遍历方式不一样。
	// for循环操作
    //for (int row = 0; row < height; row++)
	//{
	//	for (int col = 0; col < width; col++)
	//	{
	//		// 灰度图
	//		if (dims == 1)
	//		{
	//			int pv = image.at<uchar>(row, col); // 每个像素值是字节类型的,强制转换成整形,uchar范围是(0,255),也就是每个像素的范围
	//			image.at<uchar>(row, col) = 255 - pv; // 255减,还在255范围内 取反,灰度图会黑白相反
	//		}
	//		// 彩色图
	//		if (dims == 3)
	//		{
	//			Vec3b bgr = image.at<Vec3b>(row, col); // 基于数组下标
	//			image.at<Vec3b>(row,col)[0] = 255 - bgr[0];
	//			image.at<Vec3b>(row,col)[1] = 255 - bgr[1];
	//			image.at<Vec3b>(row,col)[2] = 255 - bgr[2];
	//		}

	//	}
	//}
	// 指针遍历
	for (int row = 0; row < height; row++)
	{
		uchar* current_row = image.ptr<uchar>(row); 
		for (int col = 0; col < width; col++)
		{
			// 灰度图
			if (dims == 1)
			{
				int pv = *current_row;
				*current_row++ = 255 - pv; 
			}
			// 彩色图
			if (dims == 3)
			{
				*current_row++ = 255 - *current_row;
				*current_row++ = 255 - *current_row;
				*current_row++ = 255 - *current_row;
				
			}

		}
	}
	imshow("pixel_re_wr", image);
}

(3)main函数中添加mat_creation_demo 

#include<opencv2\opencv.hpp>
#include<iostream>
#include<quickopencv.h>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
	
	Mat src = imread("D:\\Deeyea\\Learning\\cat.jpg"); // 8位,通道为B G R
	if (src.empty())
	{
		printf("无法加载图片\n");
	}
	//namedWindow("show", WINDOW_FREERATIO);
	
	imshow("image", src);

	QuickDemo qd;// 创建对象
	qd.pixel_visit_demo(src); // 图像对象的创建与赋值
	waitKey(0); 
	destroyAllWindows;
	return 0;
}

 结果如下图所示:

二、相关知识总结 

2.1 获取图像宽高以及通道数

int width = image.cols;
int height = image.rows;
int dims = image.channels(); 

2.2 图像像素遍历以及取反 

(1)at<typename>(i,j) 是opencv中图像遍历函数,可以取到任何类型的图像上的点。

(2)Vec3b是图像像素值的类型。

(3)image.at<Vec3b>(i,j)[k]:是指取出彩色图像中i行j列第k通道的颜色点。

if (dims == 3)
	{
	    Vec3b bgr = image.at<Vec3b>(row, col); // 基于数组下标
	    image.at<Vec3b>(row,col)[0] = 255 - bgr[0];
	    image.at<Vec3b>(row,col)[1] = 255 - bgr[1];
	    image.at<Vec3b>(row,col)[2] = 255 - bgr[2];
	}

 2.3 ptr相关知识

ptr是opencv中Mat数据类型指针,用来指定某一像素的位置。

Mat image = imread("image.jpg"); // 创建对象
uchar* p1 = image.ptr<uchar>(0); // p1指向image第一行第一个元素的指针
uchar* p2 = image.ptr<uchar>(1); // p2指向image第二行第一个元素的指针
uchar* p3 = image.ptr<uchar>(0)[1]; // p3指向image第一行第二个元素的指针

 2.4 ++i与i++

 独立使用时++i 和 i++二者效果一样,就是 i=i+1。表达式中i++取i的值参与运算,而++i取i+1的值参与运算。举例 a = ++i,相当于 i=i+1; a = i; a = i++,相当于 a = i; i=i+1。

uchar* current_row = image.ptr<uchar>(row); 
if (dims == 1)
			{
				int pv = *current_row;
				*current_row++ = 255 - pv; 
			}

 *current_row获取像素值,赋值给pv,255-pv为取反操作,赋值给 *current_row,然后current_row+1,指向下一元素地址。

相关参考:

(1)++i与i++的区别_Sueko的博客-CSDN博客_++i 和i++

(2)*与++的优先级关系_不会写代码的美年达的博客-CSDN博客_*和++的优先级

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值