一:代码
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.图像求导:
也就是说后一个像素点减去前一个像素
参考: 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:用双阈值算法检测和连接边缘。
本人小白,有些错误,请多多指正,非常感谢!!!