计算机视觉篇:一:opencv的基本操作,卷积。

一:调用摄像头的操作。

#include <opencv.hpp>//opencv 的头文件
#include <iostream>
using namespace cv;
using namespace std;


void main(){
Mat Frame;//创建一个Mat 对象,是一个矩阵。
VideoCapture cap(0);//读摄像头文件,0代表电脑摄像头,1,2,代表USB的。也可以是路径,表示一个文件位置。

while(true)
{
	cap>>Frame;//cap类似c++中的cin,cap读取一帧图像保存在frame中,后一个参数为0表示可以调节窗口大小。若为1表示不可以。
        imshow("frame",Frame);//把Frame矩阵中的内容显示出来。第一个参数表示窗口名称
        waitKey(10);//等待10毫秒,为0表示无限延迟。
}


二:使用opencv读取一张图片。图片要放在工程文件夹里。


Mat impgrag=imread("124.jpg",1);//读一张名为“123”的图片,存入矩阵中。后一个参数为1表示RGB三通道,为0为灰度图。
 cvtColor(impgrag,impgrag,CV_RGB2GRAY);//用于转换颜色,有四个参数,第一个为读取的矩阵名称,第二个为输出矩阵名称,第三个表示转换为灰度图。

 imshow("124",impgrag);//显示图片
 waitKey(0);
 cout<<(int)impgrag.at<uchar>(1,1)<<endl;//读取第一行第一列的像素值,并转化为int输出。

注:

关于灰度图和彩色图:

灰度图是单通道存储,值为0~255

  • 彩色图是三通道存储,即 R(red) G(green) B(blue) 
    • 需要注意的是在图像矩阵中,列数为行数的三倍,并且是以 B G R 的顺序存储的



三:创建Mat 矩阵。类似Matlab的用法

 Mat image=Mat::ones(5,5,CV_64FC1);//动态二维数组,ones表示元素全为1,行数,列数可以是变量。创建一个5*5的浮点型矩阵
Mat image=Mat::eyes(5,5,CV_64FC1);//单位矩阵
 cout<<image<<endl;//cout 用于输出5*5的全1矩阵。
image.inv();//矩阵转置
image.copyTo();//矩阵拷贝

注:CV_64FC1即单通道double型 
F即float浮点型,是32位的,那么64位的double表示方法即64F_(注意在opencv中没有D的表示)_,类似的还有8位无符号字符 uchar – 8U 
C 即 Channel,即通道


四:对图像求导。//这种处理方法是用中心像素点的右像素点减左像素点。

VideoCapture cap(0);
	while(true)
	{
		Mat 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);
			}
		}

五:利用卷积的方法

卷积就是加权求和。

形象的说: 利用卷积可以实现对图像模糊处理,边缘检测,产生轧花效果的图像。首先,我们有一个二维的滤波器矩阵(有个高大上的名字叫卷积核)和一个要处理的二维图像。然后,对于图像的每一个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,然后加起来,作为该像素位置的值。这样就完成了滤波过程。


卷积的作用是什么呢:利用卷积可以实现对图像的模糊处理和边缘检测。

接下来还是对上述的菊花照片进行卷积处理。思路就是先是两个for循环遍历图像矩阵中的每一个元素,但每一行两边的元素无法处理。


while (true)  
{  
   
    Mat frame=imread("124.jpg",1);
    cvtColor(frame, frame, CV_RGB2GRAY);  
Mat model = Mat(1, 3, CV_64FC1);//创建1*3大小的求导卷积核 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);//内层求加权和放在sum中 } } dimg.at<uchar>(i, j - 1) = (uchar)sum; //把sum值放在dimg矩阵中 } } imshow("123", dimg); //输出矩阵 waitKey(10); }

处理后的结果如图所示:

给出的卷积核不同,对图像的处理效果就不同。

接下来介绍图像处理中广泛应用的高斯模糊

六:利用高斯卷积和进行高斯模糊。首先必须理解高斯模糊的概念,推荐看一下百度百科。http://baike.baidu.com/link?url=Hjew2I6o5g5eeJPzvjx5WQWgf99cGuao2el3SPXqgBgLP_a1POLKyRXbyX1C6vqv28rRrXWC4FRZrHb25cWf-XQq8ytpLOQx7zRb9A5AHGDGVPda5kcbfs0Itx3OE1D6

高斯模糊的实质是利用了正态分布去生成对应的权值矩阵(卷积核);下面的代码实现了调取摄像头并对图像进行高斯模糊。

//创建高斯模糊卷积核,实质是利用正态分布。
double sigma=0.5;//标准差simga
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];//sum这个函数返回的是scale类  这个类本身有4个通道 sum函数把值放在了0通道 val[0]是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);  
  
    }  


这里就不贴图表示效果了。


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

GaussianBlur(image, image, cvSize(5, 5), 10, 10); // 高斯模糊
Canny(image, image, 100, 100);  // candy算子


这个函数实现的效果如图:

Sobel(image, image, 0, 1, 1); // sobel 算子


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值