null OpenCV实例 OpenCV实例OpenCV例程 OpenCV例程 常用的标准图
图像文件读入和显示
图像创建、保存和复制
Canny边缘检测
Canny边缘检测2
轮廓(contour)检测
轮廓(contour)检测2
图像旋转与缩放
读视频文件和运动物体检测
Hough线段检测
鼠标绘图
snake轮廓例子
离散傅立叶变换(DFT)
人脸检测
QR分解
绘制贝赛尔Bezier曲线
使用DirectShow采集图像
设定跟踪目标图片的改进
摄像头标定
施密特正交化
高斯背景建模
图像缩放
高级图像处理初步
常用的标准图 常用的标准图 Lena.jpg (90KB, MIME type: image/jpeg) Fruits.jpg (81KB, MIME type: image/jpeg) Fruits.jpg (81KB, MIME type: image/jpeg) Baboon.jpg (176KB, MIME type: image/jpeg) Baboon.jpg (176KB, MIME type: image/jpeg) Airplane.jpg (84KB, MIME type: image/jpeg) Airplane.jpg (84KB, MIME type: image/jpeg) 图像文件读入和显示
图像文件读入和显示
/**********************************************
* OpenCV example
* By Shiqi Yu 2006
**********************************************/
#include "cv.h"
#include "highgui.h"
int main( int argc, char** argv )
{
IplImage* pImg; //声明IplImage指针
//载入图像
if( argc == 2 &&
(pImg = cvLoadImage( argv[1], 1)) != 0 )
{nullcvNamedWindow( "Image", 1 );//创建窗口
cvShowImage( "Image", pImg );//显示图像
cvWaitKey(0); //等待按键
cvDestroyWindow( "Image" );//销毁窗口
cvReleaseImage( &pImg ); //释放图像
return 0;
}
return -1;
}
图像创建、保存和复制 图像创建、保存和复制 /**************************************************
* cvLoadImage, cvSaveImage, cvCreateImage, cvCopy以及图像显示的例子
**************************************************/
/***********************************************************************
* OpenCV example
* By Shiqi Yu 2006
***********************************************************************/
#include "cv.h"
#include "highgui.h"
int main( int argc, char** argv )
{
IplImage* pImg; //声明IplImage指针
null//载入图像,强制转化为Gray
if( argc == 3 &&
(pImg = cvLoadImage( argv[1], 0)) != 0 )
{
IplImage* pImg2 = cvCreateImage(cvGetSize(pImg),
pImg->depth,
pImg->nChannels);
cvCopy(pImg, pImg2, NULL);
cvSaveImage(argv[2], pImg2);//把图像写入文件
cvNamedWindow( "Image", 1 );//创建窗口
cvShowImage( "Image", pImg );//显示图像
cvWaitKey(0); //等待按键
cvDestroyWindow( "Image" );//销毁窗口
cvReleaseImage( &pImg ); //释放图像
cvReleaseImage( &pImg2 ); //释放图像
return 0;
}
return -1;
}
Canny边缘检测 Canny边缘检测 /**************************************************
* cvCanny:Canny边缘检测
**************************************************/
/***********************************************************************
* OpenCV example
* By Shiqi Yu 2006
***********************************************************************/
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
int main( int argc, char** argv )
{
//声明IplImage指针
IplImage* pImg = NULL;
IplImage* pCannyImg = NULL;
//载入图像,强制转化为Gray
if( argc == 2 &&
(pImg = cvLoadImage( argv[1], 0)) != 0 )
{
null//为canny边缘图像申请空间
pCannyImg = cvCreateImage(cvGetSize(pImg),
IPL_DEPTH_8U,
1);
//canny边缘检测
cvCanny(pImg, pCannyImg, 50, 150, 3);
//创建窗口
cvNamedWindow("src", 1);
cvNamedWindow("canny",1);
//显示图像
cvShowImage( "src", pImg );
cvShowImage( "canny", pCannyImg );
cvWaitKey(0); //等待按键
//销毁窗口
cvDestroyWindow( "src" );
cvDestroyWindow( "canny" );
//释放图像
cvReleaseImage( &pImg );
cvReleaseImage( &pCannyImg );
return 0;
}
return -1;
}
Canny边缘检测2 Canny边缘检测2 运行结果: 代码: 代码: #ifdef _CH_
#pragma package
#endif
#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#endif
char wndname[] = "Edge";
char tbarname[] = "Threshold";
IplImage *image = 0, *cedge = 0, *gray = 0, *edge = 0;
null// define a trackbar callback
void on_trackbar(int h)
{
cvSmooth( gray, edge, CV_BLUR, 3, 3, 0, 0 );
cvNot( gray, edge );
// Run the edge detector on grayscale
cvCanny(gray, edge, (float)h, (float)h*3, 3);
cvZero( cedge );
// copy edge points
cvCopy( image, cedge, edge );
cvShowImage(wndname, cedge);
}
nullint main( int argc, char** argv )
{
char* filename = argc == 2 ? argv[1] : (char*)"fruits.jpg";
int edge_thresh = 1;
if( (image = cvLoadImage( filename, 1)) == 0 )
return -1;
// Create the output image
cedge = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 3);
// Convert to grayscale
gray = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1);
edge = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1);
cvCvtColor(image, gray, CV_BGR2GRAY);
null// Create a window
cvNamedWindow(wndname, 1);
// create a toolbar
cvCreateTrackbar(tbarname, wndname, &edge_thresh, 100, on_trackbar);
// Show the image
on_trackbar(0);
// Wait for a key stroke; the same function arranges events processing
cvWaitKey(0);
cvReleaseImage(&image);
cvReleaseImage(&gray);
cvReleaseImage(&edge);
cvDestroyWindow(wndname);
return 0;
}
#ifdef _EiC
main(1,"edge.c");
#endif
轮廓(contour)检测 轮廓(contour)检测 /**************************************************
* 轮廓检测
* 主要函数:
* cvFindContours
* cvDrawContours
**************************************************/
/***********************************************************************
* OpenCV example
* By Shiqi Yu 2006
***********************************************************************/
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
int main( int argc, char** argv )
{
//声明IplImage指针
IplImage* pImg = NULL;
IplImage* pContourImg = NULL nullCvMemStorage * storage = cvCreateMemStorage(0);
CvSeq * contour = 0;
int mode = CV_RETR_EXTERNAL;
if( argc == 3)
if(strcmp(argv[2], "all") == 0)
mode = CV_RETR_CCOMP; //内外轮廓都检测
//创建窗口
cvNamedWindow("src", 1);
cvNamedWindow("contour",1);
//载入图像,强制转化为Gray
if( argc >= 2 &&
(pImg = cvLoadImage( argv[1], 0)) != 0 )
{
nullcvShowImage( "src", pImg );
//为轮廓显示图像申请空间
//3通道图像,以便用彩色显示
pContourImg = cvCreateImage(cvGetSize(pImg),
IPL_DEPTH_8U,
3);
//copy source image and convert it to BGR image
cvCvtColor(pImg, pContourImg, CV_GRAY2BGR);
//查找contour
cvFindContours( pImg, storage, &contour, sizeof(CvContour),
mode, CV_CHAIN_APPROX_SIMPLE);
}
else
{
//销毁窗口
cvDestroyWindow( "src" );
cvDestroyWindow( "contour" );
cvReleaseMemStorage(&storage);
return -1;
}
null//将轮廓画出
cvDrawContours(pContourImg, contour,
CV_RGB(0,0,255), CV_RGB(255, 0, 0),
2, 2, 8);
//显示图像
cvShowImage( "contour", pContourImg );
cvWaitKey(0);
//销毁窗口
cvDestroyWindow( "src" );
cvDestroyWindow( "contour" );
//释放图像
cvReleaseImage( &pImg );
cvReleaseImage( &pContourImg );
cvReleaseMemStorage(&storage);
return 0;
}
轮廓(contour)检测2 轮廓(contour)检测2 运行结果:
代码 代码 #ifdef _CH_
#pragma package
#endif
#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#include
#endif
#define w 500
int levels = 3;
CvSeq* contours = 0;null
void on_trackbar(int pos)
{
IplImage* cnt_img = cvCreateImage( cvSize(w,w), 8, 3 );
CvSeq* _contours = contours;
int _levels = levels - 3;
if( _levels <= 0 ) // get to the nearest face to make it look more funny
_contours = _contours->h_next->h_next->h_next;
cvZero( cnt_img );
cvDrawContours( cnt_img, _contours, CV_RGB(255,0,0), CV_RGB(0,255,0), _levels, 3, CV_AA, cvPoint(0,0) );
cvShowImage( "contours", cnt_img );
cvReleaseImage( &cnt_img );
}
nullint main( int argc, char** argv )
{
int i, j;
CvMemStorage* storage = cvCreateMemStorage(0);
IplImage* img = cvCreateImage( cvSize(w,w), 8, 1 );
cvZero( img );
for( i=0; i < 6; i++ ){
int dx = (i%2)*250 - 30;
int dy = (i/2)*150;
CvScalar white = cvRealScalar(255);
CvScalar black = cvRealScalar(0);
if( i == 0 )
{
for( j = 0; j <= 10; j++ )
{
double angle = (j+5)*CV_PI/21;
cvLine(img, cvPoint(cvRound(dx+100+j*10-80*cos(angle)),
cvRound(dy+100-90*sin(angle))),
cvPoint(cvRound(dx+100+j*10-30*cos(angle)),
cvRound(dy+100-30*sin(angle))), white, 1, 8, 0);
}
}nullcvEllipse( img, cvPoint(dx+150, dy+100), cvSize(100,70), 0, 0, 360, white, -1, 8, 0 );
cvEllipse( img, cvPoint(dx+115, dy+70), cvSize(30,20), 0, 0, 360, black, -1, 8, 0 );
cvEllipse( img, cvPoint(dx+185, dy+70), cvSize(30,20), 0, 0, 360, black, -1, 8, 0 );
cvEllipse( img, cvPoint(dx+115, dy+70), cvSize(15,15), 0, 0, 360, white, -1, 8, 0 );
cvEllipse( img, cvPoint(dx+185, dy+70), cvSize(15,15), 0, 0, 360, white, -1, 8, 0 );
cvEllipse( img, cvPoint(dx+115, dy+70), cvSize(5,5), 0, 0, 360, black, -1, 8, 0 );
cvEllipse( img, cvPoint(dx+185, dy+70), cvSize(5,5), 0, 0, 360, black, -1, 8, 0 );
cvEllipse( img, cvPoint(dx+150, dy+100), cvSize(10,5), 0, 0, 360, black, -1, 8, 0 );
cvEllipse( img, cvPoint(dx+150, dy+150), cvSize(40,10), 0, 0, 360, black, -1, 8, 0 );
cvEllipse( img, cvPoint(dx+27, dy+100), cvSize(20,35), 0, 0, 360, white, -1, 8, 0 );
cvEllipse( img, cvPoint(dx+273, dy+100), cvSize(20,35), 0, 0, 360, white, -1, 8, 0 );
}nullcvNamedWindow( "image", 1 );
cvShowImage( "image", img );
cvFindContours( img, storage, &contours, sizeof(CvContour),
CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );
// comment this out if you do not want approximation
contours = cvApproxPoly( contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 3, 1 );
nullcvNamedWindow( "contours", 1 );
cvCreateTrackbar( "levels+3", "contours", &levels, 7, on_trackbar );
on_trackbar(0);
cvWaitKey(0);
cvReleaseMemStorage( &storage );
cvReleaseImage( &img );
return 0;
}
#ifdef _EiC
main(1,"");
#endif
图像旋转与缩放 图像旋转与缩放 #include "cv.h"
#include "highgui.h"
#include "math.h"
int main (int argc, char **argv)
{
IplImage *src = 0;
IplImage *dst = 0;
/* the first command line parameter must be image file name */
if ((argc == 2) && (src = cvLoadImage (argv[1], -1)) != 0)
{
int delta = 1;
int angle = 0;
int opt = 0; // 1: 旋转加缩放
// 0: 仅仅旋转
double factor;
nulldst = cvCloneImage (src);
cvNamedWindow ("src", 1);
cvShowImage ("src", src);
for (;;)
{
float m[6];
// Matrix m looks like:
//
// [ m0 m1 m2 ] ===> [ A11 A12 b1 ]
// [ m3 m4 m5 ] [ A21 A22 b2 ]
//
CvMat M = cvMat (2, 3, CV_32F, m);
int w = src->width;
int h = src->height;
if (opt) // 旋转加缩放
factor = (cos (angle * CV_PI / 180.) + 1.0) * 2;
else null// 仅仅旋转
factor = 1;
m[0] = (float) (factor * cos (-angle * 2 * CV_PI / 180.));
m[1] = (float) (factor * sin (-angle * 2 * CV_PI / 180.));
m[3] = -m[1];
m[4] = m[0];
// 将旋转中心移至图像中间
m[2] = w * 0.5f;
m[5] = h * 0.5f;
// dst(x,y) = A * src(x,y) + b
cvZero (dst);
cvGetQuadrangleSubPix (src, dst, &M);
cvNamedWindow ("dst", 1);
cvShowImage ("dst", dst);
if (cvWaitKey (1) == 27) //ESC
break;
angle = (int) (angle + delta) % 360;
} // for-loop
}
return 0;
}读视频文件和运动物体检测 读视频文件和运动物体检测 /**************************************************
* 背景建模,运动物体检测
*
**************************************************/
/***********************************************************************
* OpenCV example
* By Shiqi Yu 2006
***********************************************************************/
#include
#include
#include
#include nullint main( int argc, char** argv )
{
//声明IplImage指针
IplImage* pFrame = NULL;
IplImage* pFrImg = NULL;
IplImage* pBkImg = NULL;
CvMat* pFrameMat = NULL;
CvMat* pFrMat = NULL;
CvMat* pBkMat = NULL;
CvCapture* pCapture = NULL;
int nFrmNum = 0;
null//创建窗口
cvNamedWindow("video", 1);
cvNamedWindow("background",1);
cvNamedWindow("foreground",1);
//使窗口有序排列
cvMoveWindow("video", 30, 0);
cvMoveWindow("background", 360, 0);
cvMoveWindow("foreground", 690, 0);
nullif( argc > 2 )
{
fprintf(stderr, "Usage: bkgrd [video_file_name]\n");
return -1;
}
//打开摄像头
if (argc ==1)
if( !(pCapture = cvCaptureFromCAM(-1)))
{
fprintf(stderr, "Can not open camera.\n");
return -2;
}
//打开视频文件
if(argc == 2)
if( !(pCapture = cvCaptureFromFile(argv[1])))
{
fprintf(stderr, "Can not open video file %s\n", argv[1]);
return -2;
}null//逐帧读取视频
while(pFrame = cvQueryFrame( pCapture ))
{
nFrmNum++;
//如果是第一帧,需要申请内存,并初始化
if(nFrmNum == 1)
{
pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);
pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
null//转化成单通道图像再处理
cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);
cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
cvConvert(pFrImg, pFrameMat);
cvConvert(pFrImg, pFrMat);
cvConvert(pFrImg, pBkMat);
}
else
{
cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
cvConvert(pFrImg, pFrameMat);
//高斯滤波先,以平滑图像
//cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);
//当前帧跟背景图相减
cvAbsDiff(pFrameMat, pBkMat, pFrMat);null//二值化前景图
cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);
//进行形态学滤波,去掉噪音
//cvErode(pFrImg, pFrImg, 0, 1);
//cvDilate(pFrImg, pFrImg, 0, 1);
//更新背景
cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);
//将背景转化为图像格式,用以显示
cvConvert(pBkMat, pBkImg);
null//显示图像
cvShowImage("video", pFrame);
cvShowImage("background", pBkImg);
cvShowImage("foreground", pFrImg);
//如果有按键事件,则跳出循环
//此等待也为cvShowImage函数提供时间完成显示
//等待时间可以根据CPU速度调整
if( cvWaitKey(2) >= 0 )
break;
}
}
null//销毁窗口
cvDestroyWindow("video");
cvDestroyWindow("background");
cvDestroyWindow("foreground");
//释放图像和矩阵
cvReleaseImage(&pFrImg);
cvReleaseImage(&pBkImg);
cvReleaseMat(&pFrameMat);
cvReleaseMat(&pFrMat);
cvReleaseMat(&pBkMat);
cvReleaseCapture(&pCapture);
return 0;
}
Hough线段检测 Hough线段检测 检测结果: null/* This is a standalone program. Pass an image name as a first parameter of the program.
Switch between standard and probabilistic Hough transform by changing "#if 1" to "#if 0" and back */
#include
#include
#include
int main(int argc, char** argv)
{
const char* filename = argc >= 2 ? argv[1] : "pic1.png";
IplImage* src = cvLoadImage( filename, 0 );
IplImage* dst;
IplImage* color_dst;
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines = 0;
int i;
nullif( !src )
return -1;
dst = cvCreateImage( cvGetSize(src), 8, 1 );
color_dst = cvCreateImage( cvGetSize(src), 8, 3 );
cvCanny( src, dst, 50, 200, 3 );
cvCvtColor( dst, color_dst, CV_GRAY2BGR );
#if 0
lines = cvHoughLines2( dst, storage, CV_HOUGH_STANDARD, 1,
CV_PI/180, 100, 0, 0 );
for( i = 0; i < MIN(lines->total,100); i++ )
{
float* line = (float*)cvGetSeqElem(lines,i);
float rho = line[0];
float theta = line[1];
CvPoint pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
null
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, CV_AA, 0 );
}
#else
lines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 50, 50, 10 );
for( i = 0; i < lines->total; i++ ){
CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 3, CV_AA, 0 );}
#endif
cvNamedWindow( "Source", 1 );
cvShowImage( "Source", src );
cvNamedWindow( "Hough", 1 );
cvShowImage( "Hough", color_dst );
cvWaitKey(0);
return 0;
}鼠标绘图 鼠标绘图 null#ifdef _CH_
#pragma package
#endif
#include "cv.h"
#include "highgui.h"
#include
#include
IplImage* inpaint_mask = 0;
IplImage* img0 = 0, *img = 0, *inpainted = 0;
CvPoint prev_pt = {-1,-1};nullvoid on_mouse( int event, int x, int y, int flags, void* zhang)
{
if( !img )
return;
if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )
prev_pt = cvPoint(-1,-1);
else if( event == CV_EVENT_LBUTTONDOWN )
prev_pt = cvPoint(x,y);
else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )
{
CvPoint pt = cvPoint(x,y);
if( prev_pt.x < 0 )
prev_pt = pt;
cvLine( inpaint_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );
cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );
prev_pt = pt;
cvShowImage( "image", img );
}
}nullint main( int argc, char** argv )
{
char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg";
if( (img0 = cvLoadImage(filename,-1)) == 0 )
return 0;
printf( "Hot keys: \n"
"\tESC - quit the program\n"
"\tr - restore the original image\n"
"\ti or ENTER - run inpainting algorithm\n"
"\t\t(before running it, paint something on the image)\n" );
cvNamedWindow( "image", 1 );
img = cvCloneImage( img0 );
inpainted = cvCloneImage( img0 );
inpaint_mask = cvCreateImage( cvGetSize(img), 8, 1 );
cvZero( inpaint_mask );
cvZero( inpainted );
cvShowImage( "image", img );
cvShowImage( "watershed transform", inpainted );
cvSetMouseCallback( "image", on_mouse, 0 );nullfor(;;)
{
int c = cvWaitKey(0);
if( (char)c == 27 )
break;
if( (char)c == 'r' )
{
cvZero( inpaint_mask );
cvCopy( img0, img,0 );
cvShowImage( "image", img );
}
if( (char)c == 'i' || (char)c == '\n' )
{
cvNamedWindow( "inpainted image", 1 );
cvInpaint( img, inpaint_mask, inpainted, 3, CV_INPAINT_TELEA );
cvShowImage( "inpainted image", inpainted );
}
}
return 1;
}
Snake轮廓例子Snake轮廓例子opencv例子里没有提供cvsnakeimage的使用方法,在此整理一个例子,可以形象的看看snake算法的结果,大致做法是:
首先设定域值分割,把基本的轮廓找出来,见图中蓝色轮廓线,再将轮廓点传入cvSnakeImage函数,计算出绿色的snake轮廓线。
其中参数alpha代点相互靠拢的权值(0-1.0),beta表示弯曲能量(越小越容易弯曲)(0-1.0),gamma表示整体能量(0-1.0)。其中参数我自己也不确定具体的范围,最好自己更改不同的范围试试. null程序运行结果 null// TrainingTools.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include #include
#include #include
#include
#include
IplImage *image = 0 ; //原始图像
IplImage *image2 = 0 ; //原始图像
copy using namespace std;
int Thresholdness = 141;
int ialpha = 20;
int ibeta=20;
int igamma=20; nullvoid onChange(int pos) {
if(image2)
cvReleaseImage(&image2);
if(image)
cvReleaseImage(&image);
image2 = cvLoadImage(“grey.bmp”,1); //显示图片
image= cvLoadImage(“grey.bmp”,0); cvThreshold(image,image,Thresholdness,255,CV_THRESH_BINARY); //分割域值
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contours = 0;
cvFindContours( image, storage, &contours, sizeof(CvContour), //寻找初始化轮廓 CV_RETR_EXTERNAL , CV_CHAIN_APPROX_SIMPLE ); nullcvFindContours( image, storage, &contours, sizeof(CvContour),
//寻找初始化轮廓 CV_RETR_EXTERNAL ,CV_CHAIN_APPROX_SIMPLE );
if(!contours)
return ;
int length = contours->total;
if(length<10) return ;
CvPoint* point = new CvPoint[length]; //分配轮廓点 C
vSeqReader reader;
CvPoint pt= cvPoint(0,0);
CvSeq *contour2=contours;
cvStartReadSeq(contour2, &reader);
for (int i = 0; i < length; i++) {
CV_READ_SEQ_ELEM(pt, reader);
point[i]=pt; }
cvReleaseMemStorage(&storage); null//显示轮廓曲线
for(int i=0;i
#include
#include
// Rearrange the quadrants of Fourier image so that the origin is at
// the image center
// src & dst arrays of equal size & type
void cvShiftDFT(CvArr * src_arr, CvArr * dst_arr )
{
CvMat * tmp;
CvMat q1stub, q2stub;
CvMat q3stub, q4stub;
CvMat d1stub, d2stub;
CvMat d3stub, d4stub;
CvMat * q1, * q2, * q3, * q4;
CvMat * d1, * d2, * d3, * d4;
CvSize size = cvGetSize(src_arr);
CvSize dst_size = cvGetSize(dst_arr);
int cx, cy;nullif(dst_size.width != size.width ||
dst_size.height != size.height){
cvError( CV_StsUnmatchedSizes, "cvShiftDFT", "Source and Destination
arrays must have equal sizes", __FILE__, __LINE__ );
}
if(src_arr==dst_arr){
tmp = cvCreateMat(size.height/2, size.width/2, cvGetElem