OpenCV 读写图像读写像素修改像素值(案例:图像反处理)

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV 读写图像读写像素修改像素值(案例:图像反处理)相关的知识,希望对你有一定的参考价值。

读写图像

1. imread 可以指定加载为灰度或者RGB图像。

imread功能是加载图像文件成为一个Mat对象,其中

  • 第一个参数表示图像文件名称

  • 第二个参数,表示加载的图像是什么类型,支持常见的三个参数值

    IMREAD_UNCHANGED (<0) 表示加载原图,不做任何改变
    IMREAD_GRAYSCALE ( 0)表示把原图作为灰度图像加载进来
    IMREAD_COLOR (>0) 表示把原图作为RGB图像加载进来
    

注意:OpenCV支持JPG、PNG、TIFF等常见格式图像文件加载

例如:读名为test2.jpg

// read image
Mat image = imread("test2.jpg");

2. imwrite 保存图像文件,类型由扩展名决定。

bool imwrite(
	const string& filename, 
	InputArray img, 
	const vector<int>& params=vector<int>() 
)
  • 第一个参数 const String& filename表示需要写入的文件名,必须要加上后缀,比如“123.png”。

  • 第二个参数 InputArray img表示Mat类型的图像数据。

  • 第三个参数 const std::vector& params表示为特定格式保存的参数编码,它有一个默认值std::vector< int >(),所以一般情况下不用写。

读写像素

读一个GRAY像素点的像素值(CV_8UC1)

Scalar intensity = img.at<uchar>(y, x);

或者

Scalar intensity = img.at<uchar>(Point(x, y));

读一个RGB像素点的像素值

Vec3f intensity = img.at<Vec3f>(y, x);

float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];

修改像素值

灰度图像

直接给当前灰度像素点赋值

img.at<uchar>(y, x) = 128;

RGB三通道图像

分别给三条通道赋值就行

img.at<Vec3b>(y,x)[0]=128; // blue
img.at<Vec3b>(y,x)[1]=128; // green
img.at<Vec3b>(y,x)[2]=128; // red

空白图像赋值

img = Scalar(0);

Scalar相关介绍可以参考我整理的另一篇博文:https://yangyongli.blog.csdn.net/article/details/121084843

ROI选择

Rect r(10, 10, 100, 100);
Mat smallImg = img(r);

Vec3b与Vec3F

Vec3b对应三通道的顺序是blue、green、red的uchar类型数据。

Vec3f对应三通道的float类型数据

把CV_8UC1转换到CV32F1实现如下:

src.convertTo(dst, CV_32F);

案例:图像反处理

自写

单通道反色处理

#include <iostream>
#include <math.h>
#include <opencv2/opencv.hpp>
#include<opencv2/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>  

using namespace std;
using namespace cv;

int main(int argc, char** argv)  //argumentss 参数;argc命令行参数个数;
{
	Mat src;
	src = imread("./test2.jpg");
	if (src.empty())
	{
		cout << "could not load image ...\\n" << endl;
		return -1;   //return 0 成功完成本函数;return -1 未能完成本函数
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	//---------------------------开始 进行功能处理---------------------------------------

	//**************************处理单通道的*******************************
	Mat gray_src;
	cvtColor(src, gray_src, CV_BGR2GRAY);	// 灰度处理
	namedWindow("output", CV_WINDOW_AUTOSIZE);
	imshow("output",gray_src);

	//图像的宽、高
	int height = gray_src.rows;
	int width  = gray_src.cols;

	//图像进行反色处理---单通道
	for (int row=0; row<height; row++)
	{
		for (int col=0; col<width; col++)
		{
			int gray=gray_src.at<uchar>(row, col);
			gray_src.at<uchar>(row, col)=255-gray;
		}
	}

	//显示处理后的图像
	namedWindow("gray_invert", CV_WINDOW_AUTOSIZE);
	imshow("gray_invert", gray_src);
	//**************************处理单通道的********************************/

	waitKey(0); //防止DOS一闪而过
	return 0;
}

多通道反色处理

#include <iostream>
#include <math.h>
#include <opencv2/opencv.hpp>
#include<opencv2/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>  

using namespace std;
using namespace cv;

int main(int argc, char** argv)  //argumentss 参数;argc命令行参数个数;
{
	Mat src;
	src = imread("./test2.jpg");
	if (src.empty())
	{
		cout << "could not load image ...\\n" << endl;
		return -1;   //return 0 成功完成本函数;return -1 未能完成本函数
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	//---------------------------开始 进行功能处理---------------------------------------
	//**************************处理多通道************************************
	Mat gray_src, dst;
	dst.create(src.size(), src.type());
	int height = src.rows;
	int width = src.cols;
	int nc = src.channels();

	for (int row=0; row<height; row++)
	{
		for(int col=0; col<width; col++)
		{
			if (nc==1)
			{
				int gray = gray_src.at<uchar>(row, col);
				gray_src.at<uchar>(row, col)=255-gray;
			}
			else if (nc==3)
			{
				int b=src.at<Vec3b>(row, col)[0];
				int g=src.at<Vec3b>(row, col)[1];
				int r=src.at<Vec3b>(row, col)[2];
				dst.at<Vec3b>(row, col)[0]=255-b;
				dst.at<Vec3b>(row, col)[1]=255-g;
				dst.at<Vec3b>(row, col)[2]=255-r;
			}
		}
	}

	// OpenCV自带的颜色 反处理函数
	// bitwise_not(src, dst);  //反位操作函数

	namedWindow("gray_3channels_invert", CV_WINDOW_AUTOSIZE);
	imshow("gray_3channels_invert", dst);
	//****************************处理多通道************************************
	//----------------------------结束处理图像---------------------------------------

	waitKey(0); //防止DOS一闪而过
	return 0;
}

OpenCV自带函数

#include <iostream>
#include <math.h>
#include <opencv2/opencv.hpp>
#include<opencv2/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>  

using namespace std;
using namespace cv;

int main(int argc, char** argv)  //argumentss 参数;argc命令行参数个数;
{
	Mat src;
	src = imread("./test2.jpg");
	if (src.empty())
	{
		cout << "could not load image ...\\n" << endl;
		return -1;   //return 0 成功完成本函数;return -1 未能完成本函数
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	//---------------------------开始 进行功能处理---------------------------------------
	//**************************处理多通道************************************
	Mat dst;
	dst.create(src.size(), src.type());
	
	//OpenCV自带的颜色 反处理函数
	bitwise_not(src, dst);  //反位操作函数

	namedWindow("gray_3channels_invert", CV_WINDOW_AUTOSIZE);
	imshow("gray_3channels_invert", dst);
	//****************************处理多通道************************************
	//----------------------------结束处理图像---------------------------------------

	waitKey(0); //防止DOS一闪而过
	return 0;
}

以上是关于OpenCV 读写图像读写像素修改像素值(案例:图像反处理)的主要内容,如果未能解决你的问题,请参考以下文章

opencv4opencv视频教程 C++ 5读写图像imreadimwrite读写像素at<>()修改像素值ROI区域选择(图像裁剪)RectVec3b与Vec3FCV_32F)

OpenCV-像素值读写(java版)

04 图像像素的读写操作

OpenCV之图像像素读写

OpenCV2.4+遍历读写像素方法总结及时间度量

Opencv读写文件