原创 OpenCV 图像处理常用函数

2009-3-19 12:04 6718 9 10 分类: 软件与OS

怎么访问图像元素

(坐标起点相对于图像原点 image origin 从 0 开始,或者是左上角 (img->origin=IPL_ORIGIN_TL) 或者是左下角 (img->origin=IPL_ORIGIN_BL) 


假设有 8-bit 1-通道的图像 I (IplImage* img): 

I(x,y) ~ ((uchar*)(img->imageData + img->widthStep*y))[x]


假设有 8-bit 3-通道的图像 I (IplImage* img): 

I(x,y)blue ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3]

I(x,y)green ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3+1]

I(x,y)red ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3+2]


如果增加点 (100,100) 的亮度 30 ,那么可以: 

CvPoint pt = {100,100};

((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3] += 30;

((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3+1] += 30;

((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3+2] += 30;


或者更有效的 

CvPoint pt = {100,100};

uchar* temp_ptr = &((uchar*)(img->imageData + img->widthStep*pt.y))[x*3];

temp_ptr[0] += 30;

temp_ptr[1] += 30;

temp_ptr[2] += 30;


假设有 32-bit 浮点数, 1-通道 图像 I (IplImage* img): 

I(x,y) ~ ((float*)(img->imageData + img->widthStep*y))[x]


现在,通用方法:假设有 N-通道,类型为 T 的图像:

I(x,y)c ~ ((T*)(img->imageData + img->widthStep*y))[x*N + c]

或者你可使用宏 CV_IMAGE_ELEM( image_header, elemtype, y, x_Nc )

I(x,y)c ~ CV_IMAGE_ELEM( img, T, y, x*N + c )


也有针对各种图像(包括 4-通道)和矩阵的函数(cvGet2D, cvSet2D), 但是它们都很慢. 

--------------------------------------------------------------------------------


如何访问矩阵元素?

方法是类似的 (都是针对 0 起点的列和行) 


设有 32-bit 浮点数的实数矩阵 M (CvMat* mat): 

M(i,j) ~ ((float*)(mat->data.ptr + mat->step*i))[j]


设有 64-bit 浮点数的复数矩阵 M (CvMat* mat): 

Re M(i,j) ~ ((double*)(mat->data.ptr + mat->step*i))[j*2]

Im M(i,j) ~ ((double*)(mat->data.ptr + mat->step*i))[j*2+1]


设有单通道矩阵,有宏 CV_MAT_ELEM( matrix, elemtype, row, col ), 例如对 32-bit 浮点数的实数矩阵

M(i,j) ~ CV_MAT_ELEM( mat, float, i, j ),

假如初始化 3x3 单位阵:

CV_MAT_ELEM( mat, float, 0, 0 ) = 1.f;

CV_MAT_ELEM( mat, float, 0, 1 ) = 0.f;

CV_MAT_ELEM( mat, float, 0, 2 ) = 0.f;

CV_MAT_ELEM( mat, float, 1, 0 ) = 0.f;

CV_MAT_ELEM( mat, float, 1, 1 ) = 1.f;

CV_MAT_ELEM( mat, float, 1, 2 ) = 0.f;

CV_MAT_ELEM( mat, float, 2, 0 ) = 0.f;

CV_MAT_ELEM( mat, float, 2, 1 ) = 0.f;

CV_MAT_ELEM( mat, float, 2, 2 ) = 1.f;




--------------------------------------------------------------------------------


如何在 OpenCV 中处理我自己的数据

设你有 300x200 32-bit 浮点数 image/array, 也就是对一个有 60000 个元素的数组. 


int cols = 300, rows = 200;

float* myarr = new float[rows*cols];


// step 1) initializing CvMat header

CvMat mat = cvMat( rows, cols,

                   CV_32FC1, // 32-bit floating-point, single channel type

                   myarr // user data pointer (no data is copied)

                   );

// step 2) using cv functions, e.g. calculating l2 (Frobenius) norm

double norm = cvNorm( &mat, 0, CV_L2 );


...

delete myarr;


其它情况在参考手册中有描述.见 cvCreateMatHeader, cvInitMatHeader, cvCreateImageHeader, cvSetData etc. 

--------------------------------------------------------------------------------


如何加载和显示图像

/* usage: prog <image_name> */

#include "cv.h"

#include "highgui.h"


int main( int argc, char** argv )

{

    IplImage* img;

    if( argc == 2 && (img = cvLoadImage( argv[1], 1)) != 0 )

    {

        cvNamedWindow( "Image view", 1 );

        cvShowImage( "Image view", img );

        cvWaitKey(0); // very important, contains event processing loop inside

        cvDestroyWindow( "Image view" );

        cvReleaseImage( &img );

        return 0;

    }

    return -1;

}


 


void cvLaplace (IplImage* src, IplImage* dst, int apertureSize=3);

void cvSobel (IplImage* src, IplImage* dst, int dx, int dy, int apertureSize=3);

void cvCanny (IplImage* img, IplImage* edges, double lowThresh, double highThresh, int apertureSize=3);


void cvPreCornerDetect (IplImage* img, IplImage* corners, Int apertureSize);

void cvCornerEigenValsAndVecs (IplImage* img, IplImage* eigenvv, int blockSize, int apertureSize=3);

void cvCornerMinEigenVal (IplImage* img, IplImage* eigenvv, int blockSize, int apertureSize=3);

void cvGoodFeaturesToTrack (IplImage* image, IplImage* eigImage, IplImage* tempImage, CvPoint2D32f* corners, int* cornerCount, double qualityLevel,double minDistance);

//对已经粗检测出的角点进行亚像素精准定位

void cvFindCornerSubPix (IplImage* img, CvPoint2D32f* corners, int count,CvSize win, CvSize zeroZone, CvTermCriteria criteria);


//金字塔分解与重构

void cvPyrDown (IplImage* src, IplImage* dst, IplFilter filter=IPL_GAUSSIAN_5x5);

void cvPyrUp (IplImage* src, IplImage* dst, IplFilter filter=IPL_GAUSSIAN_5x5);


void cvThreshold (IplImage* src, IplImage* dst, float thresh, float maxvalue,CvThreshType type);


void cvProject3D ( CvPoint3D32f* points3D, int count, CvPoint2D32f* points2D,int xindx, int yindx);


void cvFindFundamentalMatrix (int* points1, int* points2, int numpoints, int method, CvMatrix3* matrix);


//很好用的平滑函数

void cvSmooth( const CvArr* src, CvArr* dst,int smoothtype=CV_GAUSSIAN,int param1=3, int param2=0, double param3=0 );

CV_BLUR_NO_SCALE CV_BLUR CV_GAUSSIAN CV_MEDIAN CV_BILATERAL


其他辅助函数:

void cvPutText( CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color );


cvCvtColor(image, gray, CV_BGR2GRAY);//彩色图像灰度化


cvCvtPlaneToPix( planes[0], planes[1], planes[2], 0, currentimage);

cvSplit(colorimage,plane[0],plane[1],plane[2],0);

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2012-12-16 10:24

xiexie
相关推荐阅读
zhangshaobing517_935512703 2011-03-21 01:28
KC24RT-300调试笔记
项目中需要使用LED驱动器,主要是为了让一串LED发出的光照一致,所以在试验中采用LED串联的方式比较好点,LED并联容易导致LED发光的 不均匀以及寿命减少。我在项目中采用金升阳公司的KC24RT-...
zhangshaobing517_935512703 2010-11-19 14:53
线程中CreateEvent和SetEvent及WaitForSingleObj
首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面.CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象.EVENT有两种状态:发信...
zhangshaobing517_935512703 2010-11-15 13:29
VS2008 BEGIN
Visual Studio 2008环境与VC6.0的环境存在着比较大的区别,下面就一些小小的区别在这里做一些探讨,欢迎指教!1、如果是调试控制台程序,很多时候点击“启动调试”后是一闪而过,此时可有两...
zhangshaobing517_935512703 2010-11-01 20:38
使用MFC的数组类
 MFC的数组类支持的数组类似于C++中的常规数组,可以存放任何数据类型。C++的常规数组在使用前必须将其定义成能够容纳所有可能需要的元素,而MFC数组类创建的对象可以根据需要动态地增大或减小,数组的...
zhangshaobing517_935512703 2010-09-07 13:14
循环
 循环设计的注意的事情:(1)双重循环的跳出问题,break只挑出所在的循环,如果使用双层FOR循环,单个BREAK就不可能跳出所有的双层(2)在迭代的时候,注意起始和终止的条件,尤其是终止问题(3)...
zhangshaobing517_935512703 2010-09-02 01:09
图像处理改进
1.特征点提取的算法  标志点的提取算法对结果的影响虽然没有经过试验或者计算的推算,每1个pix的偏差对结果的影响有多大,但是不可避免的,要想获得高精度的  测量结果,高精度的提取对结果的影响还是很大...
EE直播间
更多
我要评论
1
9
关闭 站长推荐上一条 /1 下一条