使用的是opencv3.0 vs2012版本
程序的头文件
#include <opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
以下是程序的几个例子
void main()
{
//打开摄像头进行预览的程序
VideoCapture cap(0);//0,1,2代表摄像头,0代表默认摄像头,也可以写路径,自己电脑上保存的视频
while(true)
{
Mat frame;//创建一帧
cap>>frame;//读取一帧图像保存在frame里
//新建一个没有图像的窗口 名称为123 namedWindow("123",0);
namedWindow("123",0);//0 窗口可拖动调大小 1不可拖动
imshow("123",frame);//显示图像 123代表窗口名称
waitKey(30);//waitKey()函数的功能是不断刷新图像,频率时间为delay,单位为ms。
}
}
黑白图片为二值图,每个像素点的灰度都可以用uchar表示 范围为0-255 为单通道 彩色图有三通道(RGB红绿蓝),四通道(RGBA红绿蓝+透明度)
在opencv中行称为row 列称为col 而且彩色图的色块从左到右排列为BGR排列
下面程序的作用是读取一个彩色图片转换为灰色图片 图片放置:右击工程列表的project,选择“在文件资源管理器中打开文件夹”,然后放进去一张照片
void main()
{
//读取一个彩色图片转换为灰色图片
//Mat imggray=imread("123.png",0);//读取一个名称为123.png的图片 0为灰度图 1为彩色图
Mat imggray=imread("123.png",1);
cvtColor(imggray,imggray,CV_RGB2GRAY);//转换图像 第一个为原图像,第二个为输出图像,第三个为转换方法(RGB转为灰色)
imshow("123",imggray);//显示图片
waitKey(0);//waitKey()函数的功能是不断刷新图像,频率时间为delay,单位为ms。
system("pause");//暂停程序防止程序执行完毕自动退出
}
如果要读取某个点的像素值可以在代码中添加:
cout<<(int)imggray.at<uchar>(1,1)<<endl;//读取第一行第一列灰度值 读取为char,强转为int
图像其实就是一个矩阵的表示,使用opencv函数操作矩阵:
void main()
{
//Mat imggray=imread("123.png",0);//读取一个名称为123的图片 0为灰度图 1为彩色图
//Mat image=Mat(5,5,CV_64FC1);//创建一个5行5列的图像(矩阵) (创建了一个动态(可以用参数改变)二维数组) 创建了一个矩阵
//Mat image=Mat::zeros(5,5,CV_64FC1);//zeros全部置0
//Mat image=Mat::ones(5,5,CV_64FC1);//ones全部置1
Mat image=Mat::eye(5,5,CV_64FC1);//eye 填充为单位矩阵
Mat imgone=Mat::ones(5,5,CV_64FC1);//ones 全部填充为1
Mat sum=image+imgone;//矩阵的相加 可以直接+ - * / 输出
cout<<sum<<endl;//直接输出矩阵
//cout<<image.at<double>(0,0);
//cout<<image<<endl;
system("pause");//暂停程序防止程序自动退出
}
转置一个矩阵的例子:
void main()
{
Mat image=Mat::eye(5,5,CV_64FC1);//eye 单位矩阵
image.t();//t 转置矩阵 (此处有一大堆方法用)
cout<<image<<endl;//直接输出矩阵
}
对图像进行手动写式子求导:
void main()
{
//写一个图像的求导 手动求导
VideoCapture cap(0);
while(true)
{
Mat frame;
cap>>frame;
cvtColor(frame,frame,CV_RGB2GRAY);
cout<<"row行"<<frame.rows<<"cols列"<<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);//像新建的图像中添加变换后的图像
}
}
namedWindow("123",0);
imshow("123",dimg);
waitKey(10);
}
}
使用卷积模版计算求导:
void main()
{
//写一个图像的求导 卷积求导 模版为(1,0,-1)
VideoCapture cap(0);
while(true)
{
Mat frame;
cap>>frame;
cvtColor(frame,frame,CV_RGB2GRAY);
cout<<"row行"<<frame.rows<<"cols列"<<frame.cols<<endl;//输出自己摄像头所读取的行和列
Mat model=Mat(1,3,CV_64FC1);//定义一个卷积模版
Mat dimg=Mat(frame.rows,frame.cols-2,CV_8UC1);//由于求的过程中无法对横的第一个元素和最后一个元素进行卷积求导,所以-2
model.at<double>(0,0)=1;//对卷积模版赋值
model.at<double>(0,1)=0;
model.at<double>(0,2)=-1;
for(int i=0;i<frame.rows;i++)
{
for(int j=1;j<frame.cols-1;j++)
{
double sum=0;
double half=model.cols/2;//居中式卷积求导
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;
}
}
namedWindow("123",0);
imshow("123",dimg);
waitKey(10);
}
}
对图像进行手动高斯变换(使图像变得模糊):
void main()
{
//高斯化操作 图片模糊
double sigma=0.5;
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));//exp即为e的N次方
}
}
double gssum=sum(gauss).val[0];//sum.val对矩阵所有元素求和
for(int i=-2;i<3;i++)
{
for(int j=-2;j<3;j++)
{
gauss.at<double>(i+2,j+2)/=gssum;//高斯的归一化操作 为了使图像的亮度变化不大
}
}
//以上为创建一个高斯变换矩阵对象
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;//每次都需要对sum进行置零
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;
}
}
namedWindow("123",0);
imshow("123",dimg);
waitKey(10);
}
}
调用api实现其他图像变换:
void main()
{
VideoCapture cap(0);
while(true)
{
Mat frame;
cap>>frame;
cvtColor(frame,frame,CV_RGB2GRAY);
//GaussianBlur(frame,frame,CvSize(5,5),50,50);//使用一个函数直接实现高斯变换
//Canny(frame,frame,100,100);//边缘画出(检测边缘)
//Sobel(frame,frame,0,1,1);//另一种边缘画出的方法
imshow("123",frame);
waitKey(10);
}
}
注释了三种变换,可以依次取消注释观看效果