opencv 第一次培训 学习笔记

时间:2021-08-20 20:49:32

一:代码

1.调用摄像头

#include<opencv.hpp>

#include<iostream>
using namespace std;
using namespace cv;
void main()
{
	VideoCapture cap("0");//调用摄像头的一个opencv方法
	while (true){
		Mat frame;//创建一个矩阵
		cap >> frame;//把镜头的内容传给矩阵

		namedWindow("132", 0);//创建一个窗口
		imshow("132", frame);//把矩阵存的图像显示到窗口132
		waitKey(30);
		

	}
2. 读取图片30.jpg,放到工程下可以直接读,也可以写相对路径,0为灰度,1为rgb三通道,并开启一个窗口,显示出来。

        Mat imagegrag=imread("30.jpg",1);//读一张图片,存入到矩阵,1为rgb三通道,0为灰度图
	cvtColor(imagegrag, imagegrag, CV_RGB2GRAY);//将rgb三通道图转为灰度图
	cout << (int)imagegrag.at<uchar>(1, 1) << endl; 
	imshow("123", imagegrag);
3.Mat对象的一些用法

	cout << image<< endl;
	Mat imageone = Mat::ones(5, 5, CV_64FC1);//创建一个5*5全1矩阵
	cout << imageone << endl;
	Mat image = Mat::eye(5,5,CV_64FC1);//创建一个单位矩阵,矩阵可以直接运算
4.对图像求导

	VideoCapture cap(0);
	while (true)
	{
		Mat frame;
		cap >> frame;
		cvtColor(frame, frame, CV_RGB2GRAY);

		cout << "row" << frame.rows << "col" << frame.cols << endl;//输出行和列

		Mat dimg = Mat(frame.rows, frame.cols - 2, CV_8UC1);
		for (int i = 0; i < frame.rows; i++){
			for (int j = 1; j < frame.cols - 1; j++){
				dimg.at<uchar>(i,j-1)=frame.at<uchar>(i, j - 1) - frame.at<uchar>(i, j+1);
			}
		}
}

5.用卷积的方法求导

	VideoCapture cap(0);
	while (true)
	{
		Mat frame;
		cap >> frame;
		cvtColor(frame, frame, CV_RGB2GRAY);

		
		Mat model = Mat(1, 3, CV_64FC1);//创建求导卷积核
		model.at<double>(0, 0) = -1;
		model.at<double>(0, 1) = 0;
		model.at<double>(0, 2) = 1;
		Mat dimg = Mat(frame.rows, frame.cols-2, CV_8UC1);
		for (int i = 0; i < frame.rows; i++){
			for (int j = 1; j < frame.cols - 1; j++){
				int half = model.cols / 2;
				double sum = 0;//外两层便利图像每个像素点
				for (int m = 0; m < model.rows; m++){
					for (int n = -half; n < model.cols-half; n++){
						sum += (double)frame.at<uchar>(i + m, j + n)*model.at<double>(m, n + half);//内俩层便利卷积核
					}
				}
				dimg.at<uchar>(i, j - 1) = (uchar)sum;
			}
		}
		imshow("123", dimg);
		waitKey(10);
	}
6.用高斯卷积核进行高斯模糊

	double sigma =50;
	Mat gauss(5, 5, CV_64FC1);
	for (int i = -2; i<3; i++)
	{
		for (int j = -2; j<3; j++)
		{
			gauss.at<double>(i + 2, j + 2) = exp(-(i*i + j*j) / (2 * sigma*sigma));
		}
	}
//创建高斯模糊卷积核
	double gssum = sum(gauss).val[0];
	for (int i = -2; i<3; i++)
	{
		for (int j = -2; j<3; j++)
		{
			gauss.at<double>(i + 2, j + 2) /= gssum;
		}
	}
//对卷积核归一化
	cout << gauss << endl;
	VideoCapture cap(0);
	while (true)
	{
		Mat frame;
		cap >> frame;
		cvtColor(frame, frame, CV_RGB2GRAY);
		Mat dimg = Mat(frame.rows - 4, frame.cols - 4, CV_8UC1);
		for (int i = 2; i < frame.rows - 2; i++){
			for (int j = 2; j < frame.cols-2; j++){
				double sum = 0;
				for (int m = 0; m < gauss.rows; m++){
					for (int n = 0; n < gauss.cols; n++){
						sum += (double)frame.at<uchar>(i + m - 2, j + n - 2)*gauss.at<double>(m,n);
					}
				}
				dimg.at<uchar>(i - 2, j - 2) = (uchar)sum;
			}
		}
		imshow("gauss", dimg);
		imshow("123", frame);
		waitKey(10);

	}

7.调用opencv的内部方法实现高斯模糊,以及边缘检测

VideoCapture cap(0);
	while (true)
	{
	Mat frame;
	cap >> frame;
	cvtColor(frame, frame, CV_RGB2GRAY);
	//GaussianBlur(frame, frame, cvSize(5, 5), 10, 10);
	//Canny(frame, frame, 100, 100);
	Sobel(frame, frame, 0, 1, 1);
	imshow("ddd",frame);
	waitKey(10);
	}

	system("pause");
}


二:现在开始知识补充

1.图像求导:

opencv 第一次培训 学习笔记

也就是说后一个像素点减去前一个像素

2.高斯模糊

参考: http://baike.so.com/doc/1546691-1635079.html

知道什么是高斯模糊,就不难理解卷积核为啥是这样的。

3.图像滤波:

据说图像是由波组成的,高频波表示边缘,低频波构成内容,有点难理解。我们可以通过滤去低频波,将图像边缘化,也可以滤去高频波,将图像模糊。

我们可以创建相应的卷积核,进行边缘检测。如canny,sobel。

4.Canny:(然而我并没有看懂,嘿嘿)

Canny边缘检测基本原理

      (1)图象边缘检测必须满足两个条件:一能有效地抑制噪声;二必须尽量精确确定边缘的位置。
      (2)根据对信噪比与定位乘积进行测度,得到最优化逼近算子。这就是Canny边缘检测算子。
     (3)类似与Marr(LoG)边缘检测方法,也属于先平滑后求导数的方法。
     Canny边缘检测算法:
      step1:用高斯滤波器平滑图象;
      step2:用一阶偏导的有限差分来计算梯度的幅值和方向;
      step3:对梯度幅值进行非极大值抑制;
      step4:用双阈值算法检测和连接边缘。
opencv 第一次培训 学习笔记


本人小白,有些错误,请多多指正,非常感谢!!!