




已阅读5页,还剩53页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
opencv二值化函数cvThresholdOpenCV 2009-03-26 16:00:07 阅读4570 评论5 字号:大中小订阅 对图像二值化函数cvThreshold的理解Threshold对数组元素进行固定阈值操作void cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type ); src 原始数组 (单通道 , 8-bit of 32-bit 浮点数). dst 输出数组,必须与 src 的类型一致,或者为 8-bit. threshold 阈值 max_value 使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值. threshold_type 阈值类型 (见讨论) 函数 cvThreshold 对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。(cvCmpS 也可以达到此目的) 或者是去掉噪声,例如过滤很小或很大象素值的图像点。本函数支持的对图像取阈值的方法由 threshold_type 确定:threshold_type=CV_THRESH_BINARY:dst(x,y) = max_value, if src(x,y)threshold 0, otherwise.threshold_type=CV_THRESH_BINARY_INV:dst(x,y) = 0, if src(x,y)threshold; dst(x,y) = max_value, otherwise.threshold_type=CV_THRESH_TRUNC:dst(x,y) = threshold, if src(x,y)threshold;dst(x,y) = src(x,y), otherwise.threshold_type=CV_THRESH_TOZERO:dst(x,y) = src(x,y), if (x,y)threshold ; dst(x,y) = 0, otherwise.threshold_type=CV_THRESH_TOZERO_INV:dst(x,y) = 0, if src(x,y)threshold ;dst(x,y) = src(x,y), otherwise.左面是图形化的阈值描述:OpenCV中矩阵数据的访问(一)(Learning OpenCV第三章2)由 keystonexu 2008-11-26 20:28 在OpenCV中有三种方式访问矩阵中的数据元素:容易的方式,困难的方式,以及正确的方式。以下先讲容易的方式和困难的方式。容易的方式最容易的方式是使用宏CV_MAT_ELEM( matrix, elemtype, row, col ),输入参数是矩阵的指针,矩阵元素类型,行,列,返回值是相应行,列的矩阵元素,例如:CvMat* mat = cvCreateMat(5,5,CV_32FC1);float element = CV_MAT_ELEM(*mat,float,3,2);以下是一个例子:#pragma comment( lib, cxcore.lib )#include cv.h#include void main()CvMat* mat = cvCreateMat(3,3,CV_32FC1);cvZero(mat);/将矩阵置0/为矩阵元素赋值CV_MAT_ELEM( *mat, float, 0, 0 ) = 1.f;CV_MAT_ELEM( *mat, float, 0, 1 ) = 2.f;CV_MAT_ELEM( *mat, float, 0, 2 ) = 3.f;CV_MAT_ELEM( *mat, float, 1, 0 ) = 4.f;CV_MAT_ELEM( *mat, float, 1, 1 ) = 5.f;CV_MAT_ELEM( *mat, float, 1, 2 ) = 6.f;CV_MAT_ELEM( *mat, float, 2, 0 ) = 7.f;CV_MAT_ELEM( *mat, float, 2, 1 ) = 8.f;CV_MAT_ELEM( *mat, float, 2, 2 ) = 9.f;/获得矩阵元素的值float element = CV_MAT_ELEM(*mat,float,2,2);printf(%fn,element);CV_MAT_ELEM宏实际上会调用CV_MAT_ELEM_PTR(matrix,row,col)宏来完成任务。CV_MAT_ELEM_PTR()宏的参数是矩阵的指针,行,列。CV_MAT_ELEM()宏和CV_MAT_ELEM_PTR()宏的区别是,在调用CV_MAT_ELEM时,指向矩阵元素的指针的数据类型已经依据输入参数中的元素类型而做了强制转换。,以下是使用CV_MAT_ELEM_PTR()来设置元素的值:#pragma comment( lib, cxcore.lib )#include cv.h#include void main()CvMat* mat = cvCreateMat(3,3,CV_32FC1);cvZero(mat);/将矩阵置0float element_0_2 = 7.7f;*(float*)CV_MAT_ELEM_PTR( *mat, 0, 2 ) ) = element_0_2;/获得矩阵元素的值float element = CV_MAT_ELEM(*mat,float,0,2);printf(%fn,element);以上使用矩阵中元素的方式很方便,但不幸的是,该宏在每次调用时,都会重新计算指针的位置。这意味着,先查找矩阵数据区中第0个元素的位置,然后,根据参数中的行和列,计算所需要的元素的地址偏移量,然后将地址偏移量与第0个元素的地址相加,获得所需要的元素的地址。所以,以上的方式虽然很容易使用,但是却不是获得矩阵元素的最好方式。特别是当你要顺序遍历整个矩阵中所有元素时,这种每次对地址的重复计算就更加显得不合理。困难的方式以上两个宏只适合获得一维或二维的矩阵(数组)元素,OpenCV提供了处理多维矩阵(数组)的方式。实际上你可以不受限制地使用N维。当访问这样一种N维矩阵中元素时,你需要使用一个系列的函数,叫做cvPtr*D,*代表1,2,3,4.,例如,cvPtr1D(),cvPtr2D(),cvPtr3D(),以及cvPtrND().以下为此系列函数的定义:cvPtr*D函数用于返回指向某数组元素的指针uchar* cvPtr1D( const CvArr* arr, int idx0, int* type=NULL );uchar* cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type=NULL );uchar* cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2, int* type=NULL );uchar* cvPtrND( const CvArr* arr, int* idx, int* type=NULL, int create_node=1, unsigned* precalc_hashval=NULL );arr输入数组(矩阵).idx0元素下标的第一个以0为基准的成员idx1元素下标的第二个以0为基准的成员idx2元素下标的第三个以0为基准的成员idx数组元素下标type可选的,表示输出参数的数据类型create_node可选的,为稀疏矩阵输入的参数。如果这个参数非零就意味着被需要的元素如果不存在就会被创建。precalc_hashval可选的,为稀疏矩阵设置的输入参数。如果这个指针非NULL,函数不会重新计算节点的HASH值,而是从指定位置获取。这种方法有利于提高智能组合数据的操作函数cvPtr*D 返回指向特殊数组元素的指针。数组维数应该与传递给函数的下标数相匹配,它可以被用于顺序存取的1D,2D或nD密集数组函数也可以用于稀疏数组,并且如果被需要的节点不存在函数可以创建这个节点并设置为0就像其它获取数组元素的函数 (cvGetReal*D, cvSetReal*D)如果元素的下标超出了范围就会产生错误很明显,如果是一维数组(矩阵),那就可以使用cvPtr1D,用参数idx0来指向要获得的第idx0个元素,返回值为指向该元素的指针,如果是二维数组(矩阵),就可以使用cvPtr2D,用idx0,idx1来指向相应的元素。如果是N维数组,则int* idx参数指向对N维数组中某元素定位用的下标序列。#pragma comment( lib, cxcore.lib )#include cv.h#include void main()CvMat* mat = cvCreateMat(3,3,CV_32FC1);cvZero(mat);/将矩阵置0/为矩阵元素赋值CV_MAT_ELEM( *mat, float, 0, 0 ) = 1.f;CV_MAT_ELEM( *mat, float, 0, 1 ) = 2.f;CV_MAT_ELEM( *mat, float, 0, 2 ) = 3.f;CV_MAT_ELEM( *mat, float, 1, 0 ) = 4.f;CV_MAT_ELEM( *mat, float, 1, 1 ) = 5.f;CV_MAT_ELEM( *mat, float, 1, 2 ) = 6.f;CV_MAT_ELEM( *mat, float, 2, 0 ) = 7.f;CV_MAT_ELEM( *mat, float, 2, 1 ) = 8.f;CV_MAT_ELEM( *mat, float, 2, 2 ) = 9.f;/获得矩阵元素(0,2)的值float *p = (float*)cvPtr2D(mat, 0, 2);printf(%fn,*p);我们使用cvPtr*D()函数的一个理由是,通过此函数,我们可以用指针指向矩阵中的某元素,并使用指针运算符,来设置该元素的值,或者,用指针运算来移动指针,指向从起始位置开始的矩阵中的其他元素。例如,我们可以用以下方式遍历矩阵中的元素:#pragma comment( lib, cxcore.lib )#include cv.h#include void main()CvMat* mat = cvCreateMat(3,3,CV_32FC1);cvZero(mat);/将矩阵置0/获得矩阵元素(0,0)的指针float *p = (float*)cvPtr2D(mat, 0, 0);/为矩阵赋值for(int i = 0; i 9; i+)*p = (float)i;p+;/打印矩阵的值p = (float*)cvPtr2D(mat, 0, 0);for(i = 0; i 9; i+)printf(%ft,*p);p+;if(i+1) % 3 = 0)printf(n);但 是要注意,以上为矩阵中元素的通道数为1时,可以用p+来访问下一个矩阵中元素,但是如果通道数不为1,例如一个三通道的二维矩阵,矩阵中每个元素的值 为RGB值,则矩阵中数据按以下方式存储:rgbrgbrgb.,因此,使用指针指向下一个元素时,就需要加上相应的通道数。举例如下:#pragma comment( lib, cxcore.lib )#include cv.h#include void main()/矩阵元素为三通道浮点数CvMat* mat = cvCreateMat(3,3,CV_32FC3);cvZero(mat);/将矩阵置0/为矩阵元素赋值/获得矩阵元素(0,0)的指针float *p = (float*)cvPtr2D(mat, 0, 0);/为矩阵赋值for(int i = 0; i 9; i+)/为每个通道赋值*p = (float)i*10; p+;*p = (float)i*10+1;p+;*p = (float)i*10+2;p+;/打印矩阵的值p = (float*)cvPtr2D(mat, 0, 0);for(i = 0; i 9; i+)printf(%2.1f,%2.1f,%2.1ft,*p,*(p+1),*(p+2);p+=3;if(i+1) % 3 = 0)printf(n);如果你不想使用指向数据的指针,而只是想获得矩阵中的数据,你还可以使用cvGet*D函数系列。如下所示,该函数系列以返回值类型划分有两种,一种返回double类型数据,另一种返回CvScalar类型数据。Get*D返回特殊的数组元素CvScalar cvGet1D( const CvArr* arr, int idx0 );CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 );CvScalar cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );CvScalar cvGetND( const CvArr* arr, int* idx );arr输入数组.idx0元素下标第一个以0为基准的成员idx1元素下标第二个以0为基准的成员idx2元素下标第三个以0为基准的成员idx元素下标数组函数cvGet*D 返回指定的数组元素。对于稀疏数组如果需要的节点不存在函数返回0 (不会创建新的节点)GetReal*D返回单通道数组的指定元素double cvGetReal1D( const CvArr* arr, int idx0 );double cvGetReal2D( const CvArr* arr, int idx0, int idx1 );double cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 );double cvGetRealND( const CvArr* arr, int* idx );arr输入数组,必须是单通道.idx0元素下标的第一个成员,以0为基准idx1元素下标的第二个成员,以0为基准idx2元素下标的第三个成员,以0为基准idx元素下标数组函 数cvGetReal*D 返回单通道数组的指定元素,如果数组是多通道的,就会产生运行时错误,而 cvGet*D 函数可以安全的被用于单通道和多通道数组,注意,该方法返回值类型是double类型的,这意味着,矩阵中如果保存的是int类型数据,不能用此系列方 法。#pragma comment(lib,cxcore.lib)#includecv.h#includevoid main()/矩阵元素为1通道浮点型数据CvMat*mat=cvCreateMat(3,3,CV_32FC1 );cvZero(mat);/将矩阵置0/为矩阵元素赋值/获得矩阵元素(0,0)的指针float *p=(float*)cvPtr2D(mat,0,0);/为矩阵赋值for(int i=0;i9;i+)/为每个通道赋值*p=(float)i*10; p+;for(i=0;i3;i+)for(int j=0;j3;j+)printf(%lft,cvGetReal2D(mat,i,j);另外,我们还有类似于cvGet*D()的方法为矩阵元素赋值:cvSetReal*D()和cvSet*D()。Set*D修改指定的数组void cvSet1D( CvArr* arr, int idx0, CvScalar value );void cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value );void cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value );void cvSetND( CvArr* arr, int* idx, CvScalar value );arr输入数组idx0元素下标的第一个成员,以0为基点idx1元素下标的第二个成员,以0为基点idx2元素下标的第三个成员,以0为基点idx元素下标数组value指派的值函数 cvSet*D 指定新的值给指定的数组元素。对于稀疏矩阵如果指定节点不存在函数创建新的节点SetReal*D修改指定数组元素值void cvSetReal1D( CvArr* arr, int idx0, double value );void cvSetReal2D( CvArr* arr, int idx0, int idx1, double value );void cvSetReal3D( CvArr* arr, int idx0, int idx1, int idx2, double value );void cvSetRealND( CvArr* arr, int* idx, double value );arr输入数组.idx0元素下标的第一个成员,以0为基点idx1元素下标的第二个成员,以0为基点idx2元素下标的第三个成员,以0为基点idx元素下标数组value指派的值函数 cvSetReal*D 分配新的值给单通道数组的指定元素,如果数组是多通道就会产生运行时错误。然而cvSet*D 可以安全的被用于多通道和单通道数组。对于稀疏数组如果指定的节点不存在函数会创建该节点。以下是一个例子:#pragma comment(lib,cxcore.lib)#includecv.h#includevoid main()/矩阵元素为三通道8位浮点数CvMat *mat=cvCreateMat(3,3,CV_32FC3 );cvZero(mat);/将矩阵置0/为矩阵元素赋值for(int i = 0; i 3; i+)for(int j = 0; j 3; j+)cvSet2D( mat, i, j, cvScalar(i*10,j*10,i*j*10) );for(i=0;i3;i+)for(int j=0;jheight*image-widthStep),單位位元組*/ char *imageData; /* 指向排列的圖像數據 */ int widthStep; /* 排列的圖像行大小,以位元組為單位 */ int BorderMode4; /* 邊際結束模式, 被OpenCV忽略 */ int BorderConst4; /* 同上 */ char *imageDataOrigin; /* 指針指向一個不同的圖像數據結構(不是必須排列的),是為了糾正圖像記憶體分配準備的 */ IplImage;IplImage結構來自於 Intel Image Processing Library(是其本身所具有的)。OpenCV 只支持其中的一個子集: alphaChannel 在OpenCV中被忽略。 colorModel 和channelSeq 被OpenCV忽略。OpenCV顏色轉換的唯一函數 cvCvtColor把原圖像的顏色空間的目標圖像的顏色空間作為一個參數。 dataOrder 必須是IPL_DATA_ORDER_PIXEL (顏色通道是交叉存取),然而平面圖像的被選擇通道可以被處理,就像COI(感興趣的通道)被設置過一樣。 align 是被OpenCV忽略的,而用 widthStep 去訪問後繼的圖像行。 不支持maskROI 。處理MASK的函數把他當作一個分離的參數。MASK在 OpenCV 里是 8-bit,然而在 IPL他是 1-bit。 tileInfo 不支持。 BorderMode和BorderConst是不支持的。每個 OpenCV 函數處理像素的鄰近的像素,通常使用單一的固定代碼邊際模式。 除了上述限制,OpenCV處理ROI有不同的要求。要求原圖像和目標圖像的尺寸或 ROI的尺寸必須(根據不同的操作,例如cvPyrDown 目標圖像的寬(高)必須等於原圖像的寬(高)除以2 1)精確匹配,而IPL處理交叉區域,如圖像的大小或ROI大小可能是完全獨立的。 編輯CvArr 不確定數組 typedef void CvArr;CvArr* 僅僅是被用於作函數的參數,用於指示函數接收的數組類型可以不止一個,如 IplImage*, CvMat* 甚至 CvSeq*. 最終的數組類型是在運行時通過分析數組頭的前4 個位元組判斷。 怎么访问图像像素 (坐标是从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*3I(x,y)green (uchar*)(img-imageData + img-widthStep*y)x*3+1I(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)pt.x*3;temp_ptr0 += 30;temp_ptr1 += 30;temp_ptr2 += 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*2Im 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
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- Hydroxynorketamine-d6-hydrochloride-生命科学试剂-MCE
- Hexanoyl-coenzyme-A-R-Hexanoyl-CoA-生命科学试剂-MCE
- HDAC6-ligand-Linker-Conjugate-1-生命科学试剂-MCE
- 2025安徽阜阳市颍州区教育局面向本区教育系统选调专职教研员6人模拟试卷及一套参考答案详解
- GM1-Sphingosine-d18-1-生命科学试剂-MCE
- 2025广东深圳市宝安区鹏晖中英文学校急聘生物教师1人考前自测高频考点模拟试题及答案详解(考点梳理)
- 2025年动力转向泵项目发展计划
- 安全培训效果确认表课件
- 2025年数字化X射线机合作协议书
- 销售合同中常见的法律纠纷
- 北京市西城区2024-2025学年高三上学期期末考试英语试卷
- 外科护理学(第七版)复习试题有答案
- 土建施工技术、工艺、重点、难点分析和解决方案
- 钣金生产车间安全培训
- 关于有两个孩子的离婚协议书(2025年版)
- 2025年江门楼盘统计表
- 《财务大数据分析》教案
- 颅脑CT检查技术讲解
- 电机维修工作流程
- 新型领域安全的主要内容
- 服务效率与服务质量的双赢策略
评论
0/150
提交评论