您的位置:首页 > 编程语言 > Qt开发

qt下OpenCV编程例子笔记二

2014-10-30 11:37 351 查看

以下例子来至http://wiki.opencv.org.cn/

1、离散傅立叶变换(DFT)

#include <cxcore.h>
#include <cv.h>
#include <highgui.h>

// 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;

if(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, cvGetElemType(src_arr));
}

cx = size.width/2;
cy = size.height/2; // image center

q1 = cvGetSubRect( src_arr, &q1stub, cvRect(0,0,cx, cy) );
q2 = cvGetSubRect( src_arr, &q2stub, cvRect(cx,0,cx,cy) );
q3 = cvGetSubRect( src_arr, &q3stub, cvRect(cx,cy,cx,cy) );
q4 = cvGetSubRect( src_arr, &q4stub, cvRect(0,cy,cx,cy) );
d1 = cvGetSubRect( dst_arr, &d1stub, cvRect(0,0,cx,cy) );
d2 = cvGetSubRect( dst_arr, &d2stub, cvRect(cx,0,cx,cy) );
d3 = cvGetSubRect( dst_arr, &d3stub, cvRect(cx,cy,cx,cy) );
d4 = cvGetSubRect( dst_arr, &d4stub, cvRect(0,cy,cx,cy) );

if(src_arr!=dst_arr){
if( !CV_ARE_TYPES_EQ( q1, d1 )){
cvError( CV_StsUnmatchedFormats, "cvShiftDFT", "Source and Destination arrays must have the same format", __FILE__, __LINE__ );
}
cvCopy(q3, d1, 0);
cvCopy(q4, d2, 0);
cvCopy(q1, d3, 0);
cvCopy(q2, d4, 0);
}
else{
cvCopy(q3, tmp, 0);
cvCopy(q1, q3, 0);
cvCopy(tmp, q1, 0);
cvCopy(q4, tmp, 0);
cvCopy(q2, q4, 0);
cvCopy(tmp, q2, 0);
}
}

int main(int argc, char ** argv)
{
const char* filename = "../Lena.jpg";
IplImage * im;

IplImage * realInput;
IplImage * imaginaryInput;
IplImage * complexInput;
int dft_M, dft_N;
CvMat* dft_A, tmp;
IplImage * image_Re;
IplImage * image_Im;
double m, M;

im = cvLoadImage( filename, CV_LOAD_IMAGE_GRAYSCALE );
if( !im )
return -1;

realInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1);
imaginaryInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1);
complexInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 2);

cvScale(im, realInput, 1.0, 0.0);
cvZero(imaginaryInput);
cvMerge(realInput, imaginaryInput, NULL, NULL, complexInput);

dft_M = cvGetOptimalDFTSize( im->height - 1 );
dft_N = cvGetOptimalDFTSize( im->width - 1 );

dft_A = cvCreateMat( dft_M, dft_N, CV_64FC2 );
image_Re = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
image_Im = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);

// copy A to dft_A and pad dft_A with zeros
cvGetSubRect( dft_A, &tmp, cvRect(0,0, im->width, im->height));
cvCopy( complexInput, &tmp, NULL );
if( dft_A->cols > im->width )
{
cvGetSubRect( dft_A, &tmp, cvRect(im->width,0, dft_A->cols - im->width, im->height));
cvZero( &tmp );
}

// no need to pad bottom part of dft_A with zeros because of
// use nonzero_rows parameter in cvDFT() call below

cvDFT( dft_A, dft_A, CV_DXT_FORWARD, complexInput->height );

cvNamedWindow("win", 0);
cvNamedWindow("magnitude", 0);
cvShowImage("win", im);

// Split Fourier in real and imaginary parts
cvSplit( dft_A, image_Re, image_Im, 0, 0 );

// Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
cvPow( image_Re, image_Re, 2.0);
cvPow( image_Im, image_Im, 2.0);
cvAdd( image_Re, image_Im, image_Re, NULL);
cvPow( image_Re, image_Re, 0.5 );

// Compute log(1 + Mag)
cvAddS( image_Re, cvScalarAll(1.0), image_Re, NULL ); // 1 + Mag
cvLog( image_Re, image_Re ); // log(1 + Mag)

// Rearrange the quadrants of Fourier image so that the origin is at
// the image center
cvShiftDFT( image_Re, image_Re );

cvMinMaxLoc(image_Re, &m, &M, NULL, NULL, NULL);
cvScale(image_Re, image_Re, 1.0/(M-m), 1.0*(-m)/(M-m));
cvShowImage("magnitude", image_Re);

cvWaitKey(-1);
return 0;
}


2、QR分解

#include <cxcore.h>
#include <vector>
using namespace std;

#pragma  comment(lib,"cxcore.lib")
#pragma  comment(lib,"highgui.lib")

void cvQR(CvMat *inputA,CvMat *q,CvMat *r)

{

CvSize inputSize=cvGetSize(inputA);
int width=inputSize.width;
int height=inputSize.height;
cvSetIdentity(q);
cvCopy(inputA,r);
vector<CvMat **> matMem;
CvMat *tempH=cvCreateMat(height,height,CV_32FC1);
matMem.push_back(&tempH);

CvMat *v=cvCreateMat(height,1,CV_32FC1);
matMem.push_back(&v);
CvMat *tempCol=cvCreateMat(height,1,CV_32FC1);
matMem.push_back(&tempCol);
CvMat *tempCol2=cvCreateMat(height,1,CV_32FC1);
matMem.push_back(&tempCol2);
CvMat *iMat=cvCreateMat(height,height,CV_32FC1);
matMem.push_back(&iMat);
CvMat *transV=cvCreateMat(1,height,CV_32FC1);
matMem.push_back(&transV);

for (int i=0; i<width; i++)
{
float b[] = {0};
CvMat temp;
cvGetCol(r,&temp,i);							//get the i col
cvCopy(&temp,tempCol);							//copy the row,don't hurt the original column
cvGetSubRect(tempCol,&temp,cvRect(0,0,1,i));	//get the header

if (temp.rows == 0 || temp.cols == 0)
memcpy(temp.data.fl,b,sizeof(float));
else
cvZero(&temp);									//make it zero

float colNorm=cvNorm(tempCol);					//get the norm of the current column
cvZero(tempCol2);								//zero the e vector

float tempval=cvGet2D(r,i,i).val[0];
cvSet2D(tempCol2,i,0,cvScalar(tempval>0?-1:1*colNorm,0,0));	//set the new value
cvSub(tempCol,tempCol2,v);						//subtract the two vectors,get v
float val2=cvNorm(v);

if (val2==0)
{
continue;
}

val2*=val2;
val2=1/val2;

cvTranspose(v,transV);
cvMatMul(v,transV,tempH);						//
cvScale(tempH,tempH,2*val2);
cvSetIdentity(iMat);							//the identity matrix
cvSub(iMat,tempH,iMat);
cvCopy(iMat,tempH);								//get the H matrix

cvTranspose(tempH,tempH);						//transpose
cvMatMul(q,tempH,q);							//q=q.h
cvGetCol(r,&temp,i);							//get the col again
cvSet2D(&temp,i,0,cvScalar(colNorm,0,0));		//set the norm

cvGetSubRect(r,&temp,cvRect(i,i+1,1,height-i-1));
if (temp.rows == 0 || temp.cols == 0)
memcpy(temp.data.fl,b,sizeof(float));
else
cvZero(&temp);									//zero the submatrix
}

for (int j=0; j<matMem.size(); j++)
{
cvReleaseMat(matMem[j]);
}
}

int main(int argc, char* argv[]){
float matData[]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7};
float rData[16];
float qData[16];
CvMat aMat=cvMat(4,4,CV_32FC1,matData);
CvMat rMat=cvMat(4,4,CV_32FC1,rData);
CvMat qMat=cvMat(4,4,CV_32FC1,qData);
cvQR(&aMat,&qMat,&rMat);
float det=cvDet(&qMat);
return 0;

}




3、绘制Bezier曲线

#include <iostream>
#include <string.h>
#include <cxcore.h>
#include <cv.h>
#include <highgui.h>
#include <fstream>

using namespace std;

const int WW_MAX_MARK_COUNT = 40; //最大40个控制点
int mark_count =4;
int conner_pt_index =-1;
CvPoint3D32f Control_pts[WW_MAX_MARK_COUNT];
IplImage *image = 0 ; //原始图像

bool is_showControlLines = true;

// 两个向量相加,p=p+q
CvPoint3D32f pointAdd(CvPoint3D32f p, CvPoint3D32f q) {
p.x += q.x;		p.y += q.y;		p.z += q.z;
return p;
}

// 向量和标量相乘p=c*p
CvPoint3D32f pointTimes(float c, CvPoint3D32f p) {
p.x *= c;	p.y *= c;	p.z *= c;
return p;
}

// 计算贝塞尔方程的值
// 变量u的范围在0-1之间
//P1*t^3 + P2*3*t^2*(1-t) + P3*3*t*(1-t)^2 + P4*(1-t)^3 = Pnew

CvPoint3D32f Bernstein(float u, CvPoint3D32f *p) {

CvPoint3D32f	a, b, c, d, r;
a = pointTimes(pow(u,3), p[0]);
b = pointTimes(3*pow(u,2)*(1-u), p[1]);
c = pointTimes(3*u*pow((1-u),2), p[2]);
d = pointTimes(pow((1-u),3), p[3]);
r = pointAdd(pointAdd(a, b), pointAdd(c, d));
return r;
}

//画控制线

void DrawControlLine(CvPoint3D32f *p) {
CvPoint pc[4];
for(int i=0;i<4;i++)

{
pc[i].x = (int)p[i].x;
pc[i].y = (int)p[i].y;
}
cvLine(image,pc[0],pc[1],CV_RGB(0,0,255),1,CV_AA,0);
cvLine(image,pc[2],pc[3],CV_RGB(0,0,255),1,CV_AA,0);
}

//得到最近Control_pts的index
int getNearPointIndex(CvPoint mouse_pt)
{
CvPoint pt;
for(int i =0; i<mark_count;i++)
{
pt.x= mouse_pt.x - (int)Control_pts[i].x;
pt.y= mouse_pt.y - (int)Control_pts[i].y;
float distance = sqrt ((float)( pt.x*pt.x + pt.y*pt.y ));
if(distance<10) return i;
}
return -1;
}

void on_mouse( int event, int x, int y, int flags, void *param )
{
if( event == CV_EVENT_LBUTTONDOWN )
{
CvPoint pt = cvPoint(x,y);
//cout<<x<<","<<y<<endl;
if(conner_pt_index >-1)
conner_pt_index = -1;
else
{
conner_pt_index = getNearPointIndex(pt);
//添加新的控制点
if(conner_pt_index==-1)
{
if(mark_count<=(WW_MAX_MARK_COUNT-1))
{
Control_pts[mark_count].x = (float)pt.x;
Control_pts[mark_count].y = (float)pt.y;
Control_pts[mark_count].z = 0;
mark_count++;
}
}
}
}
else if ( event == CV_EVENT_MOUSEMOVE ) //修改控制点坐标
{
if(conner_pt_index >-1)
{
Control_pts[conner_pt_index].x = (float)x;
Control_pts[conner_pt_index].y = (float)y;
}
}
};

int main(int argc, char* argv[])
{
CvSize image_sz = cvSize( 1000,1000);
image = cvCreateImage(image_sz , 8, 3 );
cvNamedWindow("Win",0);
cvSetMouseCallback( "Win", on_mouse, 0 );
cvResizeWindow("Win",500,500);

cout<<"==============   Bezier curve DEMO  =============="<<endl;
cout<<" "<<endl;
cout<<"1.use mouse to click control point (red) to select a control point"<<endl;
cout<<"2.use mouse to modify control point"<<endl;
cout<<"3.click mouse on somewhere to add a control point,add three points for add a new curve"<<endl;
cout<<"4.use 'W','S' to add precision or reduce precision."<<endl;
cout<<"5.press 'Z' to show control points."<<endl;
cout<<"===press ESC to exit==="<<endl;

//初始化四个控制点
Control_pts[0].x = 200;
Control_pts[0].y = 200;
Control_pts[0].z = 0;
Control_pts[1].x = 300;
Control_pts[1].y = 500;
Control_pts[1].z = 0;
Control_pts[2].x = 400;
Control_pts[2].y = 560;
Control_pts[2].z = 0;
Control_pts[3].x = 500;
Control_pts[3].y = 100;
Control_pts[3].z = 0;

int divs = 50; //控制精细度
for(;;)
{
CvPoint pt_now,pt_pre;
cvZero(image);

//绘制控制点
if(is_showControlLines)
{
for(int i =0;i<mark_count;i++)
{
CvPoint ptc;
ptc.x = (int) Control_pts[i].x;
ptc.y = (int) Control_pts[i].y;
cvCircle( image, ptc, 4, CV_RGB(255,0,0), 1,CV_AA, 0);
}
}

//绘制Bezier曲线
CvPoint3D32f *pControls = Control_pts;
for(int j=0;j<mark_count-3;j+=3)
{
for (int i=0;i<=divs;i++)
{
float u  = (float)i/divs;
CvPoint3D32f newPt = Bernstein(u,pControls);
pt_now.x = (int)newPt.x;
pt_now.y = (int)newPt.y;
if(i>0)	cvLine(image,pt_now,pt_pre,CV_RGB(230,255,0),2,CV_AA, 0 );
pt_pre = pt_now;
}
//画控制线
if(is_showControlLines)DrawControlLine(pControls);
pControls+=3;
}

cvShowImage("Win",image);
int keyCode = cvWaitKey(20);

if (keyCode==27) break;
if(keyCode=='w'||keyCode=='W') divs+=2;
if(keyCode=='s'||keyCode=='S') divs-=2;
if(keyCode=='z'||keyCode=='Z') is_showControlLines = is_showControlLines^1;
//cout<<"precision : "<<divs<<endl;
}
return 0;
}


4、施密特正交化

#include "cv.h"
#include "cxcore.h"
#include "cvaux.h"
#include <iostream>
using namespace std;

//按行操作,要被正交化的向量以行的形式放在src里面,输出正交向量以行
//的形式放dst里面,输出向量没有单位化.

void GramSchmidt(const CvMat* src, CvMat* dst)
{
int i,j;
double param,param1,param2;
assert(src!=NULL&&dst!=NULL);
assert(src->cols==dst->cols&&src->rows==dst->rows);
CvMat *VecSrc = cvCreateMat(1, src->cols, CV_64FC1);
CvMat *VecDst = cvCreateMat(1, dst->cols, CV_64FC1);
CvMat *VecTmp = cvCreateMat(1, dst->cols, CV_64FC1);
cvZero(VecSrc);
cvZero(VecDst);

for(i=0;i<dst->rows;i++)
{
cvGetRow(src, VecDst, i);
cvGetRow(src, VecSrc, i);
for(j=0;j<i;j++)
{
cvGetRow(dst, VecTmp, j);
param1=cvDotProduct(VecSrc,VecTmp);
param2=cvDotProduct(VecTmp,VecTmp);
param=param1/param2;
cvAddWeighted(VecTmp,-param,VecDst,1.0,0,VecDst);
}
memcpy(dst->data.db+i*dst->cols,VecDst->data.db,dst->cols*sizeof(double));

}
cvReleaseMat(&VecSrc);
cvReleaseMat(&VecDst);
cvReleaseMat(&VecTmp);
}

int main(int argc, char *argv[])
{
int i,j;
CvMat *Ma,*Mb;
Ma= cvCreateMatHeader( 3, 4, CV_64FC1 );
Mb=NULL;

const double a[] = { 1, 0,1, 1,
0,1, 1, 0,
0, 0,1,1,};
cvInitMatHeader( Ma, 3, 4, CV_64FC1, (void *)a);
Mb=cvCreateMat(Ma->rows,Ma->cols,CV_64FC1);
GramSchmidt(Ma,Mb);

//printf out
for(i=0;i<Mb->rows;i++)
{
for(j=0;j<Mb->cols;j++)
{
cout<<CV_MAT_ELEM(*Mb,double,i,j)<<"  ";
}
cout<<endl;
}
cout<<endl;

///////////////////////////////////
//test
CvMat *M1=cvCreateMat(1,Ma->cols,CV_64FC1);
CvMat *M2=cvCreateMat(1,Ma->cols,CV_64FC1);
double s;
for(i=0;i<Mb->rows;i++)

{
cvGetRow(Mb, M1, i);
for(j=0;j<Mb->rows;j++)
{
cvGetRow(Mb, M2, j);
s=cvDotProduct(M2,M1);
cout<<s<<"      ";
}
cout<<endl;
}
cvReleaseMat(&Ma);
cvReleaseMat(&Mb);
return 0;
}


5、分形之美

        看到有的网站搞分形艺术,才知道这个Z=Z*Z+C 如此的奇妙。于是干脆在opencv下写出来,看看。效果还不错。呵呵。这个小例子只能修改C的值,有兴趣的朋友可以自己改改代码,看能不能做出些美妙的图形。

代码提示:要获得高质量的图像,可以增加image_w,不过性能很低。

#include "cv.h"
#include "highgui.h"

const int image_w = 100;
const double a =0.0;
const double b =0.0;
const long Nmax = 255; //Z值衰减(趋向于零) 的临界
const double Rmax = 20; // Z值没有界限地增加(趋向无穷)的临界

IplImage* image =0;
int c_r_value = 60;
int c_i_value = 40;

//返回迭代的次数
int getnum(int i,int j)
{
double C_RealPart = (double)(c_r_value-50)/100*2*2; //-2 到 +2 //Julia 集合 常数C
double C_ImagPart = (double)(c_i_value-50)/100*2*2; // -2 到 +2 //Julia 集合 常数C
double RealPart = (double)i/image_w+a;
double ImagPart = (double)j/image_w+b;
int n=0;
while(n<Nmax)
{
//Z=Z*Z+C;
double ZM = RealPart*RealPart + ImagPart*ImagPart;
if(ZM>Rmax) break;
double temp_RealPart = RealPart*RealPart - ImagPart*ImagPart+C_RealPart;
double temp_ImagPart = 2*ImagPart*RealPart+C_ImagPart;
RealPart= temp_RealPart;
ImagPart= temp_ImagPart;
n++;
}
return n;
}
void onChangeimg(int pos)
{
cvZero(image);
for(int i =0;i<image_w;i++)
for(int j =0;j<image_w;j++)
{
int n1 = getnum(i,j);
int n2 = getnum(j,i);
int n3 = getnum(j,i/2);
//printf("%d,",n);
CvScalar sc1;
if(n1>Nmax-2) n1=0;
if(n2>Nmax-2) n2=0;
if(n3>Nmax-2) n3=0;

sc1.val[0] = (int)abs(255*(float)n1/Nmax);
sc1.val[1] = (int)abs(255*(float)n2/Nmax);
sc1.val[2] = (int)abs(255*(float)n3/Nmax);
cvSet2D(image,i,j,sc1);
}

double nvalue = cvNorm(image,0,CV_C);

for(int i =0;i<image_w;i++)
for(int j =0;j<image_w;j++)
{
CvScalar sc1;
CvScalar sc2 =cvGet2D(image,i,j);
sc1.val[0] = (int)abs(255*sc2.val[0]/nvalue);
sc1.val[1] = (int)abs(255*sc2.val[1]/nvalue);;
sc1.val[2] = (int)abs(255*sc2.val[2]/nvalue);;
cvSet2D(image,i,j,sc1);
}
}
int main( int argc, char** argv )
{

cvNamedWindow( "WIN", 0 );
cvCreateTrackbar( "C real", "WIN", &c_r_value, 100, onChangeimg );
cvCreateTrackbar( "C imag", "WIN", &c_i_value, 100, onChangeimg );

image = cvCreateImage( cvSize(image_w,image_w), 8, 3 );
onChangeimg(0);

for(;;)
{
cvShowImage("WIN",image);
if(cvWaitKey(40)==27) break;
}
return 0;
}


6、图像缩放

#include <cv.h>
#include <highgui.h>
#include <math.h>

int main(int argc, char* argv[])
{
IplImage *src = 0; //源图像指针
IplImage *dst = 0; //目标图像指针
float scale = 0.618; //缩放倍数为0.618倍
CvSize dst_cvsize; //目标图像尺寸

/* the first command line parameter must be image file name */
if ( argc == 2 && (src = cvLoadImage(argv[1], -1))!=0 )
{
//如果命令行传递了需要打开的图片就无须退出,所以注释掉下面一行!
//return -1;
}
else
{
src = cvLoadImage("../Lena.jpg"); //载入工作目录下文件名为“Lena.jpg”的图片。
}

dst_cvsize.width = src->width * scale; //目标图像的宽为源图象宽的scale倍
dst_cvsize.height = src->height * scale; //目标图像的高为源图象高的scale倍

dst = cvCreateImage( dst_cvsize, src->depth, src->nChannels); //构造目标图象
cvResize(src, dst, CV_INTER_LINEAR); //缩放源图像到目标图像

cvNamedWindow( "src", CV_WINDOW_AUTOSIZE ); //创建用于显示源图像的窗口
cvNamedWindow( "dst", CV_WINDOW_AUTOSIZE ); //创建用于显示目标图像的窗口

cvShowImage( "src", src ); //显示源图像
cvShowImage( "dst", dst ); //显示目标图像

cvWaitKey(-1); //等待用户响应

cvReleaseImage(&src); //释放源图像占用的内存
cvReleaseImage(&dst); //释放目标图像占用的内存
cvDestroyWindow( "src" ); //销毁窗口“src”
cvDestroyWindow( "dst" ); //销毁窗口“dst”
//void cvDestroyAllWindows(void);

return 0;
}

7、图像颜色分布直方图

#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;

int main( int argc, char** argv )
{
IplImage * src= cvLoadImage("../Test3.JPG");

IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 );
IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 );
IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 );
IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 );
IplImage* planes[] = { h_plane, s_plane };

/** H 分量划分为16个等级,S分量划分为8个等级 */
int h_bins = 16, s_bins = 8;
int hist_size[] = {h_bins, s_bins};

/** H 分量的变化范围 */
float h_ranges[] = { 0, 180 };

/** S 分量的变化范围*/
float s_ranges[] = { 0, 255 };
float* ranges[] = { h_ranges, s_ranges };

/** 输入图像转换到HSV颜色空间 */
cvCvtColor( src, hsv, CV_BGR2HSV );
cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );

/** 创建直方图,二维, 每个维度上均分 */
CvHistogram * hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );
/** 根据H,S两个平面数据统计直方图 */
cvCalcHist( planes, hist, 0, 0 );

/** 获取直方图统计的最大值,用于动态显示直方图 */
float max_value;
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );

/** 设置直方图显示图像 */
int height = 240;
int width = (h_bins*s_bins*6);
IplImage* hist_img = cvCreateImage( cvSize(width,height), 8, 3 );
cvZero( hist_img );

/** 用来进行HSV到RGB颜色转换的临时单位图像 */
IplImage * hsv_color = cvCreateImage(cvSize(1,1),8,3);
IplImage * rgb_color = cvCreateImage(cvSize(1,1),8,3);
int bin_w = width / (h_bins * s_bins);
for(int h = 0; h < h_bins; h++)
{
for(int s = 0; s < s_bins; s++)
{
int i = h*s_bins + s;
/** 获得直方图中的统计次数,计算显示在图像中的高度 */
float bin_val = cvQueryHistValue_2D( hist, h, s );
int intensity = cvRound(bin_val*height/max_value);

/** 获得当前直方图代表的颜色,转换成RGB用于绘制 */
cvSet2D(hsv_color,0,0,cvScalar(h*180.f / h_bins,s*255.f/s_bins,255,0));
cvCvtColor(hsv_color,rgb_color,CV_HSV2BGR);
CvScalar color = cvGet2D(rgb_color,0,0);

cvRectangle( hist_img, cvPoint(i*bin_w,height),
cvPoint((i+1)*bin_w,height - intensity),
color, -1, 8, 0 );
}
}

cvNamedWindow( "Source", 1 );
cvShowImage( "Source", src );

cvNamedWindow( "H-S Histogram", 1 );
cvShowImage( "H-S Histogram", hist_img );

cvWaitKey(0);
}


8、灰度模板匹配

#include <cv.h>
#include <highgui.h>
#include <stdio.h>

/*
* 结果保存在工作目录图片
*/
int main(int argc, char* argv[])
{
int i,j,ii,jj,count,countmax,targeti,targetj;
IplImage *src = 0;
IplImage *bwdst = 0;
IplImage *bwdst1 = 0;
IplImage *cannydst = 0;
IplImage *templet = 0;
CvSize templetsize, srcsize;
CvRect roiRegion;

templet = cvLoadImage("../template.png", CV_LOAD_IMAGE_GRAYSCALE);
//cvNamedWindow( "templet", 0 );
//cvShowImage( "templet", templet );
templetsize = cvGetSize(templet);

src = cvLoadImage("../Templetmatch.png", CV_LOAD_IMAGE_GRAYSCALE);
//cvNamedWindow( "src", 0 );
//cvShowImage( "src", src );
srcsize = cvGetSize(src);

//binary51
bwdst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
cvAdaptiveThreshold(src, bwdst, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 51, 5 );
//cvNamedWindow( "bwdst", 0 );
//cvShowImage( "bwdst", bwdst );
cvSaveImage("bwdst.bmp",bwdst );

//binary11
bwdst1 = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
cvAdaptiveThreshold(src, bwdst1, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 11, 5 );
//cvNamedWindow( "bwdst1", 0 );
//cvShowImage( "bwdst1", bwdst1 );
cvSaveImage("bwdst1.bmp",bwdst1 );

//canny
cannydst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
cvCanny(src, cannydst, 50, 100, 3);
//cvNamedWindow( "cannydst", 0 );
//cvShowImage( "cannydst", cannydst );
cvSaveImage("cannydst.bmp",cannydst );

//search templet region
countmax = 0;
targeti = 0;
targetj = 0;
for(i=0; i<(srcsize.height-templetsize.height); i=i+4)
{
for(j=0; j<(srcsize.width-templetsize.width); j=j+4)
{
count = 0;
for(ii=0; ii<templetsize.height; ii=ii+4)
{
for(jj=0; jj<templetsize.width; jj=jj+4)
{
if( ((uchar *)(templet->imageData + ii*templet->widthStep))[jj] !=
((uchar *)(cannydst->imageData + (i+ii)*cannydst->widthStep))[(j+jj)] )
{
count++;
}

}
}
if(countmax < count)
{
countmax = count;
targeti = i;
targetj = j;
}
printf("i=%d, countmax=%d\n",i,countmax);
}
}
//roiRegion = cvRect(0, 0, templetsize.width, templetsize.height);
//cvSetImageROI(cannydst, roiRegion);
//cvResetImageROI(cannydst);
cvRectangle(cannydst, cvPoint(targetj,targeti),cvPoint((targetj+templetsize.width),
(targeti+templetsize.height)),CV_RGB(255,255,255),5);
cvSaveImage("cannydst1.bmp",cannydst );

cvWaitKey(0);

//release
cvReleaseImage( &templet );
cvReleaseImage( &src );
//cvReleaseImage( &bwdst );
//cvReleaseImage( &bwdst1 );
cvReleaseImage( &cannydst );

return 0;
}

9、支持向量机

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>

using namespace cv;

int main()
{
// Data for visual representation
int width = 512, height = 512;
Mat image = Mat::zeros(height, width, CV_8UC3);

// Set up training data
float labels[4] = {1.0, -1.0, -1.0, -1.0};
Mat labelsMat(4, 1, CV_32FC1, labels);

float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
Mat trainingDataMat(4, 2, CV_32FC1, trainingData);

// Set up SVM's parameters
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);

// Train the SVM
CvSVM SVM;
SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);

Vec3b green(0,255,0), blue (255,0,0);
// Show the decision regions given by the SVM
for (int i = 0; i < image.rows; ++i)
for (int j = 0; j < image.cols; ++j)
{
Mat sampleMat = (Mat_<float>(1,2) << i,j);
float response = SVM.predict(sampleMat);

if (response == 1)
image.at<Vec3b>(j, i) = green;
else if (response == -1)
image.at<Vec3b>(j, i) = blue;
}

// Show the training data
int thickness = -1;
int lineType = 8;
circle( image, Point(501, 10), 5, Scalar( 0, 0, 0), thickness, lineType);
circle( image, Point(255, 10), 5, Scalar(255, 255, 255), thickness, lineType);
circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType);
circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness, lineType);

// Show support vectors
thickness = 2;
lineType = 8;
int c = SVM.get_support_vector_count();

for (int i = 0; i < c; ++i)
{
const float* v = SVM.get_support_vector(i);
circle( image, Point( (int) v[0], (int) v[1]), 6, Scalar(128, 128, 128), thickness, lineType);
}

imwrite("result.png", image); // save the image

imshow("SVM Simple Example", image); // show it to the user
waitKey(0);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv qt 编程 例子 c