OpenCV寒假学习day02

OpenCV寒假学习day02笔记

1月11日-2月8日

1.OpenCV中图像像素的读写操作

代码

#include 
#include 

using namespace cv;
using namespace std;

int main(int artc, char** argv) {
	Mat src = imread("D:/images/test.png");
	if (src.empty()) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input", WINDOW_AUTOSIZE);
	imshow("input", src);

	// 直接读取图像像素
	int height = src.rows;
	int width = src.cols;
	int ch = src.channels();
	for (int c = 0; c < ch; c++) {
		for (int row = 0; row < height; row++) {
			for (int col = 0; col < width; col++) {
				if (ch == 3) {
					Vec3b bgr = src.at<Vec3b>(row, col);
					bgr[0] = 255 - bgr[0];
					bgr[1] = 255 - bgr[1];
					bgr[2] = 255 - bgr[2];
					src.at<Vec3b>(row, col) = bgr;
				}
				else if (ch == 1) {
					int gray = src.at<uchar>(row, col);
					src.at<uchar>(row, col) = 255 - gray;
				}
			}
		}
	}
	imshow("output", src);

	// 指针读取
	Mat result = Mat::zeros(src.size(), src.type());
	int blue = 0, green = 0, red = 0;
	int gray;
	for (int c = 0; c < ch; c++) {
		for (int row = 0; row < height; row++) {
			uchar* curr_row = src.ptr<uchar>(row);
			uchar* result_row = result.ptr<uchar>(row);
			for (int col = 0; col < width; col++) {
				if (ch == 3) {
					blue = *curr_row++;
					green = *curr_row++;
					red = *curr_row++;

					*result_row++ = blue;
					*result_row++ = green;
					*result_row++ = red;
				}
				else if (ch == 1) {
					gray = *curr_row++;
					*result_row++ = gray;
				}
			}
		}
	}
	imshow("result", result);

	waitKey(0);
	return 0;
}

	

直接读取像素

// 直接读取图像像素
	int height = src.rows;
	int width = src.cols;
	int ch = src.channels();  // 读取通道数
	for (int c = 0; c < ch; c++) {
		for (int row = 0; row < height; row++) {
			for (int col = 0; col < width; col++) {
				if (ch == 3) {
					Vec3b bgr = src.at<Vec3b>(row, col); // 读取每一个像素的BGR值
					bgr[0] = 255 - bgr[0];     // 相当于取反值
					bgr[1] = 255 - bgr[1];    //  此操作即为取反色
 					bgr[2] = 255 - bgr[2];   //   BGR三个通道
					src.at<Vec3b>(row, col) = bgr;
				}
				else if (ch == 1) {
					int gray = src.at<uchar>(row, col);
					src.at<uchar>(row, col) = 255 - gray;
				}
			}
		}
	}
	imshow("output", src);

uchar及Vec3b都是图像像素值的类型
本方法缺点就是由于通过数组一个个读取,读取速度较慢。

指针读取像素

	// 指针读取
	Mat result = Mat::zeros(src.size(), src.type()); // 创建空白图像
	int blue = 0, green = 0, red = 0;
	int gray;
	for (int c = 0; c < ch; c++) {
		for (int row = 0; row < height; row++) {
			uchar* curr_row = src.ptr<uchar>(row); //每行原像素头地址
			uchar* result_row = result.ptr<uchar>(row);
			for (int col = 0; col < width; col++) {
				if (ch == 3) {
					blue = *curr_row++;
					green = *curr_row++;
					red = *curr_row++;

					*result_row++ = blue;
					*result_row++ = green;
					*result_row++ = red;
				}
				else if (ch == 1) {
					gray = *curr_row++;
					*result_row++ = gray;
				}
			}
		}
	}
	imshow("result", result);

2.OpenCV中像素算术操作

代码

#include 
#include 

using namespace cv;
using namespace std;

int main(int artc, char** argv) {
	Mat src1 = imread("D:/vcprojects/images/LinuxLogo.jpg");
	Mat src2 = imread("D:/vcprojects/images/WindowsLogo.jpg");
	if (src1.empty() || src2.empty()) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input", WINDOW_AUTOSIZE);
	imshow("input1", src1);
	imshow("input2", src2);
	int height = src1.rows;
	int width = src1.cols;

	int b1 = 0, g1 = 0, r1 = 0;
	int b2 = 0, g2 = 0, r2 = 0;
	int b = 0, g = 0, r = 0;
	Mat result = Mat::zeros(src1.size(), src1.type());
	for (int row = 0; row < height; row++) {
		for (int col = 0; col < width; col++) {
			b1 = src1.at<Vec3b>(row, col)[0];
			g1 = src1.at<Vec3b>(row, col)[1];
			r1 = src1.at<Vec3b>(row, col)[2];

			b2 = src2.at<Vec3b>(row, col)[0];
			g2 = src2.at<Vec3b>(row, col)[1];
			r2 = src2.at<Vec3b>(row, col)[2];

			result.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b1 + b2);
			result.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g1 + g2);
			result.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r1 + r2);
		}
	}
	imshow("output", result);

	Mat add_result = Mat::zeros(src1.size(), src1.type()); // 加法
	add(src1, src2, add_result);
	imshow("add_result", add_result);

	Mat sub_result = Mat::zeros(src1.size(), src1.type()); // 减法
	subtract(src1, src2, sub_result);
	imshow("sub_result", sub_result);

	Mat mul_result = Mat::zeros(src1.size(), src1.type()); // 乘法
	multiply(src1, src2, mul_result);
	imshow("mul_result", mul_result);

	Mat div_result = Mat::zeros(src1.size(), src1.type()); // 除法
	divide(src1, src2, div_result);
	imshow("div_result", div_result);

	waitKey(0);
	return 0;
}

关于saturate_cast函数
在图像处理方面,无论是加是减,乘除,都会超出一个像素灰度值的范围(0~255),saturate_cast函数的作用即是:当运算完之后,结果为负,则转为0,结果超出255,则为255。

3.Look Up Table(LUT)查找表

代码

#include 
#include 

using namespace cv;
using namespace std;
void customColorMap(Mat& image);
int main(int argc, const char* argv[])
{
	Mat src = imread("D:/vcprojects/images/cos.jpg");
	if (src.empty())
	{
		printf("could not load image...\n");
		return -1;
	}
	Mat gray, dst;
	// 使用LUT
	applyColorMap(src, dst, COLORMAP_SUMMER);
	// 显示结果
	imshow("colorMap", dst);

	cvtColor(src, gray, COLOR_BGR2GRAY);
	imshow("gray", gray);
	customColorMap(gray);

	waitKey(0);
	return 0;
}

void customColorMap(Mat& image) {
	int lut[256];
	for (int i = 0; i < 256; i++) {
		if (i < 127)
			lut[i] = 0;
		else
			lut[i] = 255;
	}
                                       // 对比度
	int h = image.rows;
	int w = image.cols;
	for (int row = 0; row < h; row++) {
		for (int col = 0; col < w; col++) {
			int pv = image.at<uchar>(row, col); 
			image.at<uchar>(row, col) = lut[pv];
		}
	}
	imshow("lut demo", image);
}


OpenCV寒假学习day02_第1张图片

applyColorMap(src,dst,COLORMAP)
-src 输入图像
-dst 输出图像
-COLORMAP LUT

4.遗留问题

2.1.1 指针遍历时的取反

5.总结

本次通过学习像素的读取方法,进而学习了像素的算术操作及LUT和套用LUT的使用方法。

你可能感兴趣的:(opencv)