opencv学习之core模块核心功能3

7 随机数发生器&绘制文字

RNG rng( 0xFFFFFFFF );//实例化一个随机数发生器对象,rng 是用数值 0xFFFFFFFF 来实例化的一个RNG对象
/// 初始化一个0矩阵
Mat image = Mat::zeros( window_height, window_width, CV_8UC3 );
/// 把它绘制到一个窗口中
imshow( window_name, image );
int Drawing_Random_Lines( Mat image, char* window_name, RNG rng )
{
  int lineType = 8;
  Point pt1, pt2;

  for( int i = 0; i < NUMBER; i++ )    //循环将重复 NUMBER 次
  {
   pt1.x = rng.uniform( x_1, x_2 );
   pt1.y = rng.uniform( y_1, y_2 );
   pt2.x = rng.uniform( x_1, x_2 );
   pt2.y = rng.uniform( y_1, y_2 );

   line( image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), 8 );
   imshow( window_name, image );      //rng.uniform(a,b) 。这指定了一个在 a 和 b 之间的均匀分布(包含 a, 但不含 b)。
   if( waitKey( DELAY ) >= 0 )
   { return -1; }
  }
  return 0;
}
//颜色的随机选取,右移8位,16位,位的与运算,确保数值在0-255
static Scalar randomColor( RNG& rng )
  {
  int icolor = (unsigned) rng;
  return Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 );
  }
putText( image, "Testing text rendering", org, rng.uniform(0,8),
         rng.uniform(0,100)*0.05+0.1, randomColor(rng), rng.uniform(1, 10), lineType);

image 上绘制文字 “Testing text rendering”
文字的左下角将用点 org 指定。
字体参数是用一个在 0-8 之间的整数来定义。
字体的缩放比例是用表达式 rng.uniform(0, 100)x0.05 + 0.1 指定(表示它的范围是0.1, 5.1)
字体的颜色是随机的 (记为 randomColor(rng))。
字体的粗细范围是从 1 到 10, 表示为 rng.uniform(1,10)

 Size textsize = getTextSize("OpenCV forever!", CV_FONT_HERSHEY_COMPLEX, 3, 5, 0);

其中前四个参数都好理解:第一个参数为文本,第二个参数为文本的字体类型,第三个参数为文本大小的倍数,第四个为文本的粗细。最后一个参数是指距离文本最低点对应的y坐标,即下面红线与蓝线的距离。

img

8 离散傅立叶变换

对一张图像使用傅立叶变换就是将它分解成正弦和余弦两部分。也就是将图像从空间域转换到频域。任一函数都可以表示成无数个正弦和余弦函数的和的形式。傅立叶变换就是一个用来将函数分解的工具。
在这里插入图片描述

转换之后的频域值是复数, 因此,显示傅立叶变换之后的结果需要使用实数图像加虚数图像, 或者幅度图像加相位图像。实际的图像处理过程中,仅仅使用了幅度图像,因为幅度图像包含了原图像的几乎所有我们需要的几何信息。

当图像的尺寸是2, 3,5的整数倍时,计算速度最快。经常通过添凑新的边缘像素的方法获取最佳图像尺寸。函数 getOptimalDFTSize()返回最佳尺寸,而函数 copyMakeBorder()填充边缘像素

Mat padded;                            //将输入图像延扩到最佳的尺寸
int m = getOptimalDFTSize( I.rows );
int n = getOptimalDFTSize( I.cols ); // 在边缘添加0
copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0));
dft(complexI, complexI);            // 变换结果很好的保存在原始矩阵中
//复数转化为幅度
split(complexI, planes);                   // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude,(实部,虚部,输出)
Mat magI = planes[0];

傅立叶变换的幅度值范围大到不适合在屏幕上显示。高值在屏幕上显示为白点,而低值为黑点,高低值的变化无法有效分辨。为了在屏幕上凸显出高低变化的连续性,我们可以用对数尺度来替换线性尺度

magI += Scalar::all(1);                    // 转换到对数尺度
log(magI, magI);

剪切和重分布幅度图象限

将上一步得到的幅度图从中间划开得到四张1/4子图像,将每张子图像看成幅度图的一个象限,重新分布即将四个角点重叠到图片中心。 这样的话原点(0,0)就位移到图像中心。

归一化

有了重分布后的幅度图,但是幅度值仍然超过可显示范围[0,1] 。我们使用 normalize()函数将幅度归一化到可显示范围。

normalize(magI, magI, 0, 1, CV_MINMAX); // 将float类型的矩阵转换到可显示图像范围
                                        // (float [0, 1]).

离散傅立叶变换的一个应用是决定图片中物体的几何方向.

9 输入输出XML和YAML文件

你的输出(和相应的输入)文件可能仅具有其中一个扩展名以及对应的文件结构。XML和YAML的串行化分别采用两种不同的数据结构: mappings (就像STL map) 和 element sequence。map中每个元素都有一个唯一的标识名供用户访问;而在sequences中你必须遍历所有的元素才能找到指定元素。

10 与 OpenCV 1 同时使用

OpenCV 2 接受按需定制。所有函数不再装入一个单一的库中。如果你仅仅需要使用OpenCV的一部分功能,使用时,你仅需要包含用到的头文件。

所有OpenCV用到的东西都被放入名字空间 cv ,你必须在名称之前冠以 cv::,或者在包含头文件后。

Mat I;          //可以使用 IplImage 或 CvMat 操作符来转换 Mat 对象。
IplImage pI = I;
CvMat    mI = I;

获取指针,转换就变得麻烦一点。可以通过调用 IplImageCvMat 操作符来获取他们的指针。

Mat I;
IplImage* pI     = &I.operator IplImage();
CvMat* mI        =  &I.operator CvMat();

OpenCV引进了一种智能指针。它将自动释放不再使用的对象。使用时,指针将被声明为 Ptr 模板的特化:

Ptr<IplImage> piI = &I.operator IplImage();

将C接口的数据结构转换为 Mat 时,可将其作为构造函数的参数传入,例如:

Mat K(piL), L;
L = Mat(pI);

程序支持两种模式:C和C++混合,以及纯C++。如果你宏定义了DEMO_MIXED_API_USE* ,程序将按第一种模式编译。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值