opencv4笔记——1、基本处理

图像的读写

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
    // 读取图像
	Mat src = imread("F:/tupian/1.jpg");
	if (src.empty()) {
		cout << "could not load image" << endl;
		return -1;
	}
	// 图像显示
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	imshow("input", src);
	Mat gray;
	// BGR转灰度图
	cvtColor(src, gray, COLOR_BGR2GRAY);
	// 图像保存
	imwrite("F:/tupian/1_gray.jpg", gray);

	waitKey(0);

	return 0;

}

Mat类

Mat类用于存储数据,利用自动内存管理技术很好的解决了内存自动释放的问题,当变量不再需要时立即释放内存
Note:如果矩阵属于多个Mat对象,当不在需要它时,最后一个使用它的对象负责清理。通过引用计数机制来实现.无论什么时候,有人拷贝一个Mat对象的信息头,都会增加矩阵的引用次数;反之,当一个头被释放后,这个计数减一;当计数为零时,矩阵会被清理

Mat对象有两部分组成(头部+数据部分):

  • 头部
    • 矩阵头(包含矩阵尺寸、存储方法、存储地址等)
    • 一个指向存储所有像素值的矩阵的指针
  • 数据部分
    • 存储所有像素值的矩阵

Mat对象的复制

  • 部分复制:只复制Mat对象的信息头和指针部分,但不复制数据部分,比如拷贝构造函数Mat B(A), 和赋值操作
  • 完全复制:将Mat对象的头部和数据部分都复制了,clone()和copyTo()
#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
    // 读取图像
	Mat src;    // 创建一个名为src的信息头
	src = imread("F:/tupian/1.jpg");   
	if (src.empty()) {
		cout << "could not load image" << endl;
		return -1;
	}
	// 图像显示
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	imshow("input", src);


    
	// 克隆 ,实现完全复制
	Mat m1 = src.clone();
	// copyTo() 实现完全复制
	Mat m2;
	src.copyTo(m2);

	// 赋值,部分复制,只复制信息头和指针
	Mat m3 = src;
	// 拷贝构造函数,部分复制,m4只复制src的头部
	Mat m4(src);

	Mat m5 = Mat::zeros(src.size(), src.type());
	Mat m6 = Mat::zeros(Size(512, 512), CV_8UC3);
	Mat m7 = Mat::ones(Size(512, 512), CV_8UC3);
	// 定义小数组
	Mat kernel = (Mat_<uchar>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	waitKey(0);
	return 0;
}

图像像素的读写

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
	// 读取图像
	Mat src;    
	src = imread("F:/tupian/1.jpg");    
	if (src.empty()) {
		cout << "could not load image" << endl;
		return -1;
	}

	// 图像显示
	namedWindow("input", CV_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];
				}
				else if (ch == 1) {
					int gray = src.at<uchar>(row, col);
					src.at<uchar>(row, col) = 255 - gray;
				}
			}
		}
	}

	// 指针读取
	Mat result = Mat::zeros(src.size(), src.type());
	int blue = 0, green = 0, red = 0;
	int gray=0;
	for (int c = 0; c < ch; ++c) {
		for (int row=0; row < height; ++row) {
			uchar* src_row = src.ptr<uchar>(row);  // 获取指向第row行的指针
			uchar* result_row = result.ptr<uchar>(row);
			for (int col = 0; col < width; ++col) {
				if (ch == 3) {
					blue = *src_row++;
					green = *src_row++;
					red = *src_row++;
					/*
					blue = src[3*col + 0];
					green = src[3*col +1];
					red = src[3*col +2];
					*/
					*result_row++ = blue;
					*result_row++ = green;
					*result_row++ = red;
				}
				else if (ch == 1) {
					gray = *src_row++;
					*result_row = gray;
				}
			}
		}
	}
	waitKey(0);

	return 0;

}

像素算术操作

  • 加 add
  • 减 subtract
  • 乘 multiply
  • 除 divide
  • saturate_cast 防溢出保护
    **Note:**图像的数据类型,大小,通道数必须相同
#include <opencv2/opencv.hpp>
#include <iostream>

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", CV_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];

			// saturate_cast 防溢出保护
			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;
}

像素逻辑操作

  • 与: bitwise_and(src1, src2, dst)
  • 或:bitwise_or(src1, src2, dst)
  • 异或:bitwise_xor(src1, src2, dst)
  • 取反:bitwise_not(src, dst)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值