1.图像滤波
这里有到两个函数cvCreateImage和 cvSmooth( image, out, CV_GAUSSIAN, 5,5,0,0 )。
cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,3)用于创建
指定大小的图像,第一个参数是尺寸,第二个参数是数据类型,
第三个参数是通道数。cvSmooth( image, out, CV_GAUSSIAN, 5,5,0,0 )
用于图像滤波,第一个参数是输入图像;第二个参数是输出图像;
第三个参数是平滑方法;5,5表示5*5邻域;
第六个参数是高斯参数的 Gaussian sigma (标准差)。
#include <stdio.h>
#include <fstream>
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "cv.h"
using namespace cv;
using namespace std;
int main( )
{
IplImage* image = cvLoadImage( "a1.ppm" );//输入图像
cvNamedWindow( "Example4-in", CV_WINDOW_AUTOSIZE );//创建显示输入图像的窗口
cvNamedWindow( "Example4-out", CV_WINDOW_AUTOSIZE );//创建显示输出图像的窗口
cvShowImage( "Example4-in", image );//显示输入图像
IplImage* out = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,3);//创建和image大小相同的图像
// 平滑
cvSmooth( image, out, CV_GAUSSIAN, 5,5,0,0 );
cvSmooth( out, out, CV_GAUSSIAN, 5, 5,0,0);
cvShowImage( "Example4-out", out );
cvReleaseImage( &out );
cvWaitKey( 0 );
cvDestroyWindow("Example4-in" );
cvDestroyWindow("Example4-out" );
cvReleaseImage( &image );
}
封装函数
1.图像缩放
cvPyrDown( in, out )使用Gaussian金字塔分解对输入图像向下采样。第一个参数是输入图像,第二个参数是输出图像,长宽为输入图像的一半。
#include <stdio.h>
#include <fstream>
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "cv.h"
using namespace cv;
using namespace std;
IplImage* doPyrDown(IplImage* in,int filter = IPL_GAUSSIAN_5x5)
{
assert( in->width%2 == 0 && in->height%2 == 0 );//长宽不为偶数退出
IplImage* out= cvCreateImage(
cvSize( in->width/2, in->height/2 ),
in->depth,
in->nChannels
);
cvPyrDown( in, out );
return( out );
};
int main( )
{
IplImage* img = cvLoadImage( "ch12_birdseye.jpg" );
IplImage* img2 = cvCreateImage( cvSize( img->width/2,img->height/2 ), img->depth, img->nChannels);
cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE );
cvNamedWindow("Example2", CV_WINDOW_AUTOSIZE );
cvShowImage("Example1", img );
img2 = doPyrDown( img );
cvShowImage("Example2", img2 );
cvWaitKey(0);
cvReleaseImage( &img );
cvReleaseImage( &img2 );
cvDestroyWindow("Example1");
cvDestroyWindow("Example2");
}
- 边缘检测
cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY)函数可以实现颜色空间的转换,第一个参数是输入图像,第二个参数是输出图像,第三个参数是转换形式——CV_BGR2GRAY表示转换为灰度图,输入需要是单通道图片;CV_BGR2HSV将图片从RGB空间转换为HSV空间,需要将rgb值归一化到0-1之间。
函数 void cvCanny( const CvArr* image,CvArr* edges,double threshold1,double threshold2, int aperture_size=3 )采用 Canny 算法发现输入图像的边缘而且在输出图像中标识这些边缘。输入是灰度图,threshold1和threshold2 当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割, aperture_size是算子内核大小。
#include <stdio.h>
#include <fstream>
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "cv.h"
using namespace cv;
using namespace std;
IplImage* doCanny(
IplImage* in,
double lowThresh,
double highThresh,
double aperture)
{
if (in->nChannels != 1)
return(0);
IplImage* out = cvCreateImage(
cvGetSize( in ),
in->depth,
1);
cvCanny( in, out, lowThresh, highThresh, aperture );
return( out );
};
int main( )
{
IplImage* img_rgb = cvLoadImage( "left01.jpg" );
IplImage* img_gry = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);
cvCvtColor(img_rgb, img_gry ,CV_BGR2GRAY);
cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );
cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );
cvShowImage("Example Gray", img_gry );
IplImage* img_cny = doCanny( img_gry, 10, 100, 3 );
cvShowImage("Example Canny", img_cny );
cvWaitKey(0);
cvReleaseImage( &img_rgb);
cvReleaseImage( &img_gry);
cvReleaseImage( &img_cny);
cvDestroyWindow("Example Gray");
cvDestroyWindow("Example Canny");
}
3.嵌套使用
有了之前封装的函数,就可以很方便的对图像做一系列的变换,比如缩小两次在进行边缘检测,代码为:
#include <stdio.h>
#include <fstream>
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "cv.h"
using namespace cv;
using namespace std;
IplImage* doCanny(
IplImage* in,
double lowThresh,
double highThresh,
double aperture)
{
IplImage* out = cvCreateImage(
cvGetSize( in ),
in->depth, //IPL_DEPTH_8U,
1);
cvCanny( in, out, lowThresh, highThresh, aperture );
return( out );
};
IplImage* doPyrDown(
IplImage* in,
int filter = IPL_GAUSSIAN_5x5)
{
// Best to make sure input image is divisible by two.
//
assert( in->width%2 == 0 && in->height%2 == 0 );
IplImage* out = cvCreateImage(
cvSize( in->width/2, in->height/2 ),
in->depth,
in->nChannels
);
cvPyrDown( in, out );
return( out );
};
int main( )
{
cvNamedWindow("Example Gray", CV_WINDOW_AUTOSIZE );
cvNamedWindow("Example Pyr", CV_WINDOW_AUTOSIZE );
cvNamedWindow("Example Canny", CV_WINDOW_AUTOSIZE );
IplImage* img_rgb = cvLoadImage("ch12_birdseye.jpg");
IplImage* out;
out = cvCreateImage( cvSize( img_rgb->width,img_rgb->height ), img_rgb->depth, 1);
cvCvtColor(img_rgb, out ,CV_BGR2GRAY);
cvShowImage("Example Gray", out );
out = doPyrDown( out );
out = doPyrDown( out );
cvShowImage("Example Pyr", out );
out = doCanny( out, 10, 100, 3 );
cvShowImage("Example Canny", out );
cvWaitKey(0);
cvReleaseImage( &out);
cvDestroyWindow("Example Gray");
cvDestroyWindow("Example Pyr");
cvDestroyWindow("Example Canny");
}
对视频的每一幅图像进行变换
#include <stdio.h>
#include <fstream>
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "cv.h"
using namespace cv;
using namespace std;
int main( ) {
cvNamedWindow( "Example2_10", CV_WINDOW_AUTOSIZE );
cvNamedWindow( "Log_Polar", CV_WINDOW_AUTOSIZE );
CvCapture* capture = cvCreateFileCapture("a2.mp4" );
if (!capture){
return -1;
}
IplImage* bgr_frame;
double fps = cvGetCaptureProperty (capture, CV_CAP_PROP_FPS);//获取帧率
printf("fps=%d\n",(int)fps);
CvSize size = cvSize(
(int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH),
(int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT)
);
printf("frame (w, h) = (%d, %d)\n",size.width,size.height);
CvVideoWriter* writer = cvCreateVideoWriter(
"D:\Documents\Visual Studio 2010\Projects\load and display an image\load and display an image\a3.mp4",
CV_FOURCC('D','X','5','0'),
fps,
size
);
IplImage* logpolar_frame = cvCreateImage(
size,
IPL_DEPTH_8U,
3
);
IplImage* gray_frame = cvCreateImage(
size,
IPL_DEPTH_8U,
1
);
while( (bgr_frame=cvQueryFrame(capture)) != NULL ) {
cvShowImage( "Example2_10", bgr_frame );
cvConvertImage( //We never make use of this gray image
bgr_frame,
gray_frame,
CV_RGB2GRAY
);
cvLogPolar( bgr_frame, logpolar_frame, //This is just a fun conversion the mimic's the human visual system
cvPoint2D32f(bgr_frame->width/2,
bgr_frame->height/2),
40,
CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS );
cvShowImage( "Log_Polar", logpolar_frame );
//Sigh, on linux, depending on your ffmpeg, this often won't work ...
cvWriteToAVI( writer, logpolar_frame );
char c = cvWaitKey(10);
if( c == 27 ) break;
}
cvReleaseVideoWriter( &writer );
cvReleaseImage( &gray_frame );
cvReleaseImage( &logpolar_frame );
cvReleaseCapture( &capture );
return 0;
}