OpenCV学習:基本的な画像操作(2つ):マットオブジェクトの使用

マットオブジェクトコンストラクターとコピー

//构造函数

Mat()
Mat(int rows,int cols, int type)            // rows 行数
Mat(Size size,int type)                     // cols 列数
Mat(int rows,int cols,const Scalar &s)      // Size 图片大小(x,y)
Mat(int ndims, const int *sizes, int type)  // ndims 矩阵维度
Mat(int ndims, const int *sizes, int type,const Scalar &s )    // 颜色 Scalar (B,G,R)

//常用方法

void copyTo(Mat mat)                  //复制到传入的Mat
void convertTo(Mat dst,int type)      //生成新的Mat,指定其数据类型
Mat clone()                           //复制后,返回新的Mat
int channels()                        //返回通道数
int  depth()                          //返回数据位深度
bool empty()                          //判断数据是否为空
uchar* ptr(i = 0)                     //返回图片像素指针,i为行索引

画像の作成とマトリックスの作成

Mat img(100,100,CV_8UC3,Scale(0,0,255));
//      宽 ,高,数据类型,填充颜色(需要与数据类型对应)
//8UC3 ->  8:位深位8bit UC:uchar 3:三个通道


int size[3] = {2,2,2};  //矩阵长,宽,高
Mat L(3,sz,CV_8UC1,Scale(0,0,255));
//矩阵维度,矩阵形状,数据类型,填充数据

Mat ml;
ml.creat(L.size(),L.type());
//用creat创建矩阵
ml = Scalar(0,0,255);
//再用Scalar来填充


//定义小数组
Mat kernel = (Mat_<float>(3,3) << 0,-1,0,-1,5,-1,0,-1,0);
//创建特殊矩阵
Mat mz = Mat::zeros(src.size,src.type);
Mat eye = Mat::eye(src.size,src.type);

部分コピーと完全コピー

  • 部分コピー:通常、Matオブジェクトのヘッダー部分とポインター部分のみがコピーされ、データ部分はコピーされません。
  • フルコピー:Matオブジェクトのヘッダーとデータ部分を一緒にコピーする場合は、copyToとcloneを使用して
Mat A = imread(imgFilePath);

//部分复制,浅拷贝
Mat B = A;
Mat C(A);

//完全复制,深拷贝
Mat D  = A.clone();
Mat E ; A.copyTo(E);

画像関連の操作

ピクセルの読み取りと書き込み

//单通道
Scalar intensity = img.at<uchar>(y,x);

//三通道
Vec3f  intensity = img.at<Vec3f>(y,x);
//Vec3f: Vec 返回一个向量   3 通道数,即Vec的大小  f 数据类型 

グレースケールに変換するいくつかの方法

  • 式変換を使用するグレー= R * 0.299 + G * 0.587 + B * 0.114
  • R、G、Bの最大値を取ります
  • R、G、Bの最小値を取る
Mat dst;
src.convertTo(dst,CV_32F);
//改变数据类型 CV_32F
//改变颜色空间 COLOR_BGR2GRAY

コードと練習

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

using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
	
	Mat src = imread("1.jpg");
	if (src.empty())
	{
		cout << "could not open image ..." << endl;
		return -1;
	}

	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);
	int rows = gray.rows;
	int cols = gray.cols;
	imshow("src", src);
	imwrite("src.jpg", src);
	imshow("gray", gray);
	imwrite("gray.jpg", gray);

	Mat ingray = gray.clone();
	//单通道
	for (int col = 0; col < cols; col++)
	{
		for (int row = 0; row < rows; row++)
		{
			int g = gray.at<uchar>(row, col);
			ingray.at<uchar>(row, col) = 255 - g;
		}
	}
	imshow("ingray", ingray);
	imwrite("ingray_pix.jpg", ingray);

	//三通道
	Mat dst;
	dst.create(src.size(), src.type());
	int height = src.rows;
	int width = src.cols;
	int nc = src.channels();

	Mat gray1(src.rows, src.cols, CV_8UC1);
    Mat gray2(src.rows, src.cols, CV_8UC1);
	gray1 = Scalar(0);
	gray2 = Scalar(0);

	for (int col = 0; col < cols; col++)
	{
		for (int row = 0; row < rows; row++)
		{
			if (nc == 1)
			{
				int t = gray.at<uchar>(row, col);
				ingray.at<uchar>(row, col) = 255 - t;
			}
			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;

				gray1.at<uchar>(row, col) = max(b, max(g, r));
				gray2.at<uchar>(row, col) = min(b, min(g, r));
				
			}
		}
	}

	//取负片 同样的有bitwise_and,bitwise_nor,bitwise_or等对像素点的逻辑运算
	Mat insrc1;
	src.copyTo(insrc1);

	bitwise_not(src, insrc1);

	imshow("insrc_pix", dst);
	imshow("insrc_bitwise",insrc1);
	imshow("gray_min", gray1);
	imshow("gray_max", gray2);
	imwrite("insrc_pix.jpg", dst);
	imwrite("insrc_bitwise.jpg", insrc1);
	imwrite("gray_min.jpg", gray1);
	imwrite("gray_max.jpg", gray2);

	waitKey(0);
	return 0;

}

                       src灰色not_graynot_src_pix

    

             not_src_bitgrey_maxgray_min

     

おすすめ

転載: blog.csdn.net/fan1102958151/article/details/106951460