C++ byte 类型 在头文件 windows.h 中
OpenCV 中,IplImage 所在头文件为 #include<highgui/highgui_c.h>
文章目录
- 1.copyTo() 函数
- 2.随机数产生器RNG
- 3.轮廓的特征矩Moment
- 4.cvGet2D() 函数
1.copyTo() 函数
??openCV中image.copyTo()有两种形式:
??● image.copyTo(imageROI),作用是把image的内容粘贴到imageROI;
??● image.copyTo(imageROI,mask),如果在 mask 中某个像素点(i,j)的值为 1(只看第一通道,所以 mask 单通道即可),则把 image.at(i, j) 处的值直接赋给 imageROI.at(i, j),如果其值为 0 则 imageROI.at(i, j) 处保留其原始像素值(黑色)。
2.随机数产生器RNG
??用OpenCV做算法的朋友们肯定为随机数烦恼过,新版本一直支持随机数产生器啦,而且还继续支持之前版本的c格式的函数,不过与时俱进,我这里介绍C++的RNG类。它可以压缩一个64位的i整数并可以得到scalar和array的随机数。目前的版本支持均匀分布随机数和Gaussian分布随机数。随机数的产生采用的是Multiply-With-Carry算法和Ziggurat算法。
??其构造函数的初始化可以传入一个64位的整型参数作为随机数产生器的初值。next可以取出下一个随机数,uniform函数可以返回指定范围的随机数,gaussian函数返回一个高斯随机数,fill则用随机数填充矩阵。
??这里介绍一个uniform的使用事项,就是比如利用它产生0~1的随机数的问题,具体代码如下:
RNG rng;
// always produces 0
double a = rng.uniform(0, 1);
// produces double from [0, 1)
double a1 = rng.uniform((double)0, (double)1);
// produces float from [0, 1)
double b = rng.uniform(0.f, 1.f);
// produces double from [0, 1)
double c = rng.uniform(0., 1.);
// may cause compiler error because of ambiguity:
// RNG::uniform(0, (int)0.999999)? or RNG::uniform((double)0, 0.99999)?
double d = rng.uniform(0, 0.999999);
??就是不能写成rng.uniform( 0 , 1),因为输入为int型参数,会调用uniform(int,int),只能产生0。请大家注意使用。
??还有一些随机数相关的函数,比如randu可以产生一个均匀分布的随机数或者矩阵,randn可以产生一个正态分布的随机数,randShuffle可以随机打乱矩阵元素。
??再简单介绍一下c版本的随机数产生器的相关函数,有cvRNG、cvRandArr、cvRandInt、cvRandReal。
RNG& rng=theRNG();
RNG& rng=theRNG();double x= (double)rng;float y= (float)rng;int z= (int)rng;
问题来了,如果进行多次运行,每次运行的结果是一样的。
可以采取另一种方式,用系统时间作为种子初始化rng。
RNG rng((unsigned)time(NULL));//当然,用这个要记得加上头函数<time.h>double x=rng.uniform((double)0,(double)255);
float y=rng.uniform(0.f,255.f);
int z=rng.uniform((int)0, (int)255 );
3.轮廓的特征矩Moment
??在OpenCV中,可以很方便的计算多边形区域的3阶特征矩,opencv中的矩主要包括以下几种:空间矩,中心矩和中心归一化矩。
class Moments {
public: ...... // 空间矩 double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; // 中心矩 double mu20, mu11, mu02, mu30, mu21, mu12, mu03; // 中心归一化矩 double nu20, nu11, nu02, nu30, nu21, nu12, nu03; }
??
空间矩的公式为:
??????????
可以知道,对于01二值化的图像,m00即为轮廓的面积。中心矩的公式为:
????????
其中:
??????????
归一化的中心矩公式为:
??????????
Hu不变矩主要是利用归一化中心矩构造了7个不变特征矩:
OpenCV中计算Hu矩的公式为:
HuMoments(const Moments& m, OutputArray hu)void HuMoments(const Moments& moments, double hu[7])
4.cvGet2D() 函数
??OpenCV CvGet2D函数作用:获取图像的颜色值
??1、若是灰度图,就是单通道图像,获取的就是每一个像素点的灰度值。
IplImage* img = cvLoadImage("test.bmp", 0);for (int i = 0; i < img->height; i++){
for (int j = 0; j < img->width; j++){
//方法一:使用cvGet2D()函数间接访问CvScalar s = cvGet2D(img, i, j);//注:i代表y轴,即height;j代表x轴,即width。printf("gray value=%f\n",s.val[0]);//方法二:使用直接访问uchar val = ((uchar *)(img->imageData + i*img->widthStep))[j]; printf("gray value=%d\n",val);}}
??2、若是彩色图,就是3通道图像,获取的就是每一个像素点的BGR值,然后分别获取B值,G值和R值。
IplImage* img = cvLoadImage("test.bmp", 1);for (int i = 0; i < img->height; i++){
for (int j = 0; j < img->width; j++){
//方法一:使用cvGet2D()函数间接访问CvScalar s=cvGet2D(img,i,j); //i代表y轴,即height;j代表x轴,即width。printf("B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]); //注意是BGR顺序//方法二:使用直接访问int bVal = ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]; int gVal = ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]; int rVal = ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]; printf("B=%d, G=%d, R=%d\n",bVal,gVal,rVal);//注意是BGR顺序}}
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
参考文章:
RNG函数:
https://blog.csdn.net/yang_xian521/article/details/6931385
https://blog.csdn.net/bella_yux/article/details/49717083
特征矩:
https://www.cnblogs.com/mikewolf2002/p/3427564.html
cvGet2D函数:
https://blog.csdn.net/u010682375/article/details/78501090