opencv图像处理教程(4)——图像像素值操作

一、读写图像

imread 可以指定加载为灰度或者RGB图像
Imwrite 保存图像文件,类型由扩展名决定
具体内容参照以前的博客:https://blog.****.net/qq_38236355/article/details/88969483

二、读写像素

读一个GRAY像素点(单通道)的像素值(CV_8UC1):

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

这里说明一下一个像素点的坐标(x,y)分别对应它所在图像的列和行(col,row)。

读一个RGB像素点(三通道)的像素值:

Vec3f intensity = img.at<Vec3f>(y, x); 
float blue = intensity.val[0]; 
float green = intensity.val[1]; 
float red = intensity.val[2];
等价于:
float blue = img.at<Vec3f>(y,x)[0];
float green = img.at<Vec3f>(y,x)[1];
float red = img.at<Vec3f>(y,x)[2];

具体<>中应填写什么类型,是由图像img的类型决定的:
<uchar>——CV_8UC1
<char>——CV_8SC1
<short>——CV_16SC1
<ushort>——CV_16UC1
<int>——CV_32SC1
<float>——CV_32FC1
<double>——CV_64FC1
<Vec3b>——CV_8UC3
<Vec3f>——CV_32FC3
注意:Vec3b对应三通道的顺序是blue、green、red的uchar类型数据。
Vec3f对应三通道的float类型数据。
把CV_8UC1转换到CV32F1实现如下:

src.convertTo(dst, CV_32F);

三、修改像素值

灰度图像

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);//灰度图
img = Scalar(0,0,0);//BGR图

ROI选择

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

整体代码演示:

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
using namespace std;

int main(int argc, char **argv)
{
	Mat src = imread("D:/opencv learning/meinv.jpg", -1);
	if (src.empty())
	{
		cout << "can not load image ..." << endl;
		return -1;
	}
	namedWindow("input image", WINDOW_AUTOSIZE);
	imshow("input image", src);

	Mat gray_src;
	cvtColor(src, gray_src, CV_BGR2GRAY);
	namedWindow("output", WINDOW_AUTOSIZE);

	int rows = gray_src.rows;
	int cols = gray_src.cols;
	//读写单通道像素值
	for (int row = 0; row < rows; row++)
	{
		for (int col = 0; col < cols; col++)
		{
			/*Scalar gray = gray_src.at<uchar>(row, col);
			gray_src.at<uchar>(row, col) = 128;//Scalar不可做像素值与数值相加减*/
			/*int gray = gray_src.at<uchar>(row, col);
			gray_src.at<uchar>(row, col) = 255 - gray; //int可做像素值与数值相加减*/
			Vec2f gray = gray_src.at<uchar>(row, col);
			gray_src.at<uchar>(row, col) = 128;
		}
	}

	//读取三通道RGB像素值
	Mat dst;
	dst.create(src.size(), src.type());
	int hight = dst.rows;
	int width = dst.cols;
	int channel = dst.channels();
	for (int row = 0; row < hight; row++)
	{
	for (int col = 0; col < width; col++)
	{
	if (channel == 1)
	{
	int gray3 = src.at<uchar>(row, col);
	dst.at<uchar>(row, col) = 255 - gray3;
	}
	else if (channel == 3)
	{/*
	int b = src.at<Vec3b>(row, col)[0];//像素点的B(蓝色)值
	int g = src.at<Vec3b>(row, col)[1];//像素点的G(绿色)值
	int r = src.at<Vec3b>(row, col)[2];//像素点的R(红色)值
	// **给像素赋值时必须是<Vec3b>代表uchar型,因为像素值是正整数,不能带小数点。
	dst.at<Vec3b>(row, col)[0] = b;
	dst.at<Vec3b>(row, col)[1] = g;
	dst.at<Vec3b>(row, col)[2] = r;
	*/
		Vec3b xiangsu = src.at<Vec3b>(row, col);
		uchar b = xiangsu.val[0];
		uchar g = xiangsu.val[1];
		uchar r = xiangsu.val[2];
		dst.at<Vec3b>(row, col)[0] = b;
		dst.at<Vec3b>(row, col)[1] = g;
		dst.at<Vec3b>(row, col)[2] = r;
		
		gray_src.at<uchar>(row, col) = min(r, min(b, g));//取R.G.B中的最小像素值给灰度图
	}
	}
	}
	Mat dat(src.size(), src.type());
	bitwise_not(src, dat);//dat为src的反差图片。
	imshow("output",dat);
	waitKey(0);
	return 0;

结果如下:
opencv图像处理教程(4)——图像像素值操作