一:代码
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:用双阈值算法检测和连接边缘。
本人小白,有些错误,请多多指正,非常感谢!!!