前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >opencv——访问图像元素(imagedata widthstep)

opencv——访问图像元素(imagedata widthstep)

作者头像
全栈程序员站长
发布2022-08-15 21:02:50
6080
发布2022-08-15 21:02:50
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

怎么访问图像元素 (坐标起点相对于图像原点 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 ), 假如初始化 3×3 单位阵: 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 中处理我自己的数据 设你有 300×200 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. ——————————————————————————–

如何加载和显示图像

#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);

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/134403.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档