【OpenCV归纳】3 在实例中学习简单函数以及数据读写



实例一
int main()
{
 IplImage*  img = cvLoadImage("6085.jpg", 1);

 IplImage* red = cvCreateImage(cvGetSize(img), img->depth, 1);
 IplImage* green = cvCreateImage(cvGetSize(img), img->depth, 1);
 IplImage* blue = cvCreateImage(cvGetSize(img), img->depth, 1);

 cvSplit(img, blue, green, red, NULL);

 IplImage* img1 = cvCloneImage(green);
 IplImage* img2 = cvCloneImage(green);

 double dMaxValue, dMinValue;
 cvMinMaxLoc(green, &dMinValue, &dMaxValue, NULL, NULL, NULL);
 printf("Max: %f\tMin: %f\n", dMaxValue, dMinValue);

 unsigned char thresh = (dMaxValue - dMinValue) / 2;
 cvSet(img1, cvScalarAll(thresh), 0);
 cvSet(img2, cvScalarAll(0), 0);

 cvCmp(green, img1, img2, CV_CMP_GE);
  
 cvSubS(green, cvScalarAll(thresh/2), green, img2);

 cvShowImage("Clone1", img1);
 cvShowImage("Clone2", img2);

 cvShowImage("Red", red);
 cvShowImage("Green", green);
 cvShowImage("Blue", blue);

 cvWaitKey(0);
 return 0;
}
cvSplit()函数可以分别复制每个通道到多个单通道图像,当然,cvSplit()函数还可以复制src的各个通道到图像dst0,dst1,dst2和dst3中。注意,目标tuxiang必须和源图像在大小和数据类型上均匹配,当然,也应该是单通道的图像。如果源图像少于4个通道,这样的话传递给cvSplit()的不必要的目标参数可以设置成NULL。
void cvSplit(const CvArr* src, CvArr* dst0, CvArr* dst1, CvArr* dst2, CvArr* dst3);

cvSet()函数能将数组的所有通道的所有值设置为指定的参数value。该cvSet()函数接受一个可选的参数,如果提供参数,那么只有那些参数mask中非0值对应的像素将被设置为指定的值。另外有cvSetZero()函数,相当于cvSet(0,0)。
void cvSet(CvArr* arr, CvScalar* value, const CvArr* mask = NULL);

void cvMinMaxLoc(const CvArr* arr, double* min_val, double* max_val, CvPoint* min_loc = NULL, CvPoint* max_loc = NULL, const CvArr* mask = NULL);该函数用于找出数组中的最大值和最小值,并且还可以返回它们的地址。计算出的最大值和最小值赋值给max_val和min_val。如果极值的位置参数非空,那极值的位置便会写入min_loc和max_loc。如果参数mask非空,那么只有arr中与参数mask中的非零的像素相对应的部分才被考虑。cvMinMaxLoc()仅仅处理单通道数组,如果有一个多通道的数组,则应该使用cvSetCOI()来对某个特定通道进行设置。cvSetCOI()函数在下文有相关介绍。
cvCmp和cvCmpS两个函数都是进行对比操作,比较两幅图像对应的像素值或将给定图像的像素值与某常标量值进行比较。cvCmp()和cvCmpS()的最后一个参数和比较操作符可以是以下的任意一个。
CV_CMP_EQ    (src1i == src2i)
CV_CMP_GT    (src1i > src2i)
CV_CMP_GE    (src1i >= src2i)
CV_CMP_LT    (src1i < src2i)
CV_CMP_LE    (src1i <= src2i)
CV_CMP_NE    (src1i != src2i)

实例二

int main()
{
 IplImage* img = cvLoadImage("6085.jpg");
 int x = 400, y = 400;
 int width = 150, height = 150;

 int add =180;
 cvSetImageROI(img, cvRect(x, y, width, height));

 cvAddS(img, cvScalar(add), img);
 cvResetImageROI(img);
 cvShowImage("Image", img);
 cvWaitKey(0);
 return 0;
}

void cvAddS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask = NULL);
void cvAdd(const CvArr* src1, const CvArr* src2,CvArr* dst, const CvArr* mask = NULL);
这两个函数都都比较简单在此不再介绍,下面我们来看看cvAddWeighted()函数。
void cvAddWeighted(const CvArr* src1, double alpha, const CvArr* src2, double beta, double gamma, CvArr* dst);
在这里包含着一个计算公式:
dst(x,y)=alpha*src1(x,y)+beta*src2(x,y)+gamma
结果图像dst和src1、src2必须是同样的像素类型,也些图像的尺寸不要求相同,但ROI必须统一尺寸。

cvSetImageROI
void cvSetImageROI(IplImage* image, CvRect rect);
void cvResetImageROI(IplImage* image);
通过cvResetImageROI()函数释放ROI是非常重要的,否则,最终只会显示你所设置的感兴趣的部分,而不是整个图像。

实例三

int main()
{
 IplImage* src = cvLoadImage("8479.jpg",1);

 IplImage* img = cvCreateImageHeader(cvSize(200, 600),
  src->depth, src->nChannels);
 IplImage* img2 = cvCreateImageHeader(cvSize(200, 600),
  src->depth, src->nChannels);

 img->imageData = (char*)cvPtr2D(src, 100, 400);
 img2->imageData = (char*)cvPtr2D(src, 400, 400);

 cvNot(img2, img2);
 cvNot(img, img);

 cvShowImage("Src", src);
 cvWaitKey(0);
 return 0;
}
cvCreateMat()
CvMat* cvCreateMat(int rows, int cols, int type);
CvMat* cvCreateMatHeader(int rows, int cols, int type);
CvMat* cvInitMatHeader(CvMat* mat, int rows, int cols, int type, void* data = NULL, int step = CV_AUTOSTEP);
CvMat cvMat(int rows, int cols, int type, void* data = NULL);
CvMat* cvCloneMat(const cvMat* mat);
void cvReleaseMat(CvMat** mat);
而以下示例中要用的cvCreateImageHeader和cvCreateMatHeader类似,大家应该能够举一反三。
cvNot()函数会将src中的每一个元素都取反,然后把结果赋值给dst。

实例四

int main()
{
 CvMat* mat = cvCreateMat(400, 400, CV_8UC3);

 for (int i = 0; i < mat->cols; i++)
 {
  for (int j = 0; j < mat->rows; j++)
  {
   cvSet2D(mat, i, j, cvScalarAll(0));
  }
 }

 cvCircle(mat, cvPoint(400 / 2, 400 / 2), 400 / 4, cvScalar(255, 255, 0), 3, 8, 0);
 cvShowImage("image", mat);
 cvWaitKey(0);
 return 0;
}
cvCircle()函数可以用来画圆,而cvEllipse()函数则用来绘制椭圆,但后者更加复杂。
void cvEllipse(CvArr* img, CvPoint center, CvSize axes, double angle, double start_angle, double end_angle, CvScalar color, int thickness = 1, int line_type = 8);其中angle是指偏离主轴的角度,从X轴开始算,逆时针方向为正。后两个则是表示弧线开始和结束位置的角度。例如,一个完整的椭圆这里就分别为0和360。
cvScale()是cvConvertScale()的一个宏,它会将shift设置为0.0。

实例五

OpenCV还支持序列化和去序列化各种数据类型(英文名分别:serialize, de-serialize),可以从磁盘中读/写YAML和XML数据。cvLoadImage()函数在前面我们已经见过了,而cvSaveImage()也是类似的。
以下是一个往磁盘中写入一个XAML文件的示例。

CvFileStorage* fs = cvOpenFileStorage(“opencv.xml”,0,CV_STORAGE_WRITE);
cvWriteInt(fs,”width”,100);
cvStartWriteStruct(fs,”height”,CV_NODE_SEQ);
cvWriteInt(fs,0,300);
cvEndWriteStruct(fs);
cvReleaseFileStorage(&fs);

时间: 2024-09-30 05:08:20

【OpenCV归纳】3 在实例中学习简单函数以及数据读写的相关文章

机器学习实例:深度学习如何做语音识别!

文章讲的是 机器学习实例:深度学习如何做语音识别,语音识别正在「入侵」我们的生活.我们的手机.游戏主机和智能手表都内置了语音识别.他甚至在自动化我们的房子.只需50美元,你就可以买到一个Amazon Echo Dot,这是一个可以让你订外卖.收听天气预报.甚至是买垃圾袋的魔术盒,而这一切你只需要大声说出: Aleax,给我订一个pizza! Echo Dot 在2015年的圣诞假期一经推出就大受欢迎,在亚马逊上面立刻售罄. 但其实语音识别已经存在很多年了,那为什么现在才成为主流呢?因为深度识别终

spring学习笔记(19)mysql读写分离后端AOP控制实例

在这里,我们接上一篇文章,利用JNDI访问应用服务器配置的两个数据源来模拟同时操作不同的数据库如同时操作mysql和oracle等.实际上,上个例子可能用来模拟mysql数据库主从配置读写分离更贴切些.既然如此,在本例中,我们就完成读写分离的模拟在web端的配置实例. 续上次的例子,关于JNDI数据源的配置和spring datasource的配置这里不再重复.下面着重加入AOP实现DAO层动态分库调用.可先看上篇文章<spring学习笔记(18)使用JNDI模拟访问应用服务器多数据源实例 >

深层学习:心智如何超越经验1.2 在混乱的世界中学习

1.2 在混乱的世界中学习 在原始人类进化的某个时刻,我们人类(更准确地讲,最终进化成智人的原始人类)开始采用一种不同寻常的生存策略.不同于其他动物,他们逐渐更多地依赖习得技能,而不是先天本能.尽管人类行为的某些方面需要遗传基因作为基础,但是我们每天的行为却主要由那些必须事先练习的动作构成,比如开车.打电话和发电子邮件,只有极少的行为无须学习,比如微笑.眨眼等.[37]虽然其他动物也会学习,但目前为止我们是更有效率的学习者.即使是通常被认为动物当中最为聪明的海豚和黑猩猩,它们吸取新知识.获取新技

看实例学VFP:删除数据表中的记录

本例对看实例学VFP:对数据表中记录进行修改一文的实例进行了一点改进,增加了"撤消"功能.程序运行时如下图: 在组合框中选择要查找的字段,在文本框中输入查找内容后单击右侧的"查找"按钮后将查找结果显示在上方的表格中,"查找"按钮变成"撤消"按钮,同时激活"删除"按钮及用于显示数据的文本框,并将当前记录(满足查询条件的记录)的值同时显示在文本框中,:单击"删除"按钮后会删除查找出来的记录刷

看实例学VFP:向数据表中添加记录时自动生成编号

本例在"看实例学VFP:向数据表中添加记录并验证输入数据是否合法"的基础上进行了改进,实现了在添加记录时不仅能够完成对输入数据的校验,还具有自动生成编号的功能.自动生成编号的相关代码加在表单的init事件及"添加"按钮的click中,在表单第一次启动或添加完记录后都会调用此段代码,实现自动生成编号的功能.运行界面如下: 本例用到了"数据1"数据库中的"网站信息表",关于该数据库的情况已经在看实例学VFP:示例数据库一文中给出,

ASM实例中使用ASMCMD工具管理ASM目录及文件

在ASM实例中,所有的存储于ASM磁盘组中的文件对于操作系统命令而言是不可访问的,因此也无法使用常规的命令来操纵ASM磁盘中的文件.所幸的是,我们有ASMCMD工具来代替操作系统命令来完成这部分工作.ASMCMD工具提供了类似于操作系统的常用命令,如ls , du ,find,cd ,rm ,mkdir等等.借助这些工具可以更轻松的完成ASM实例的相关管理工作. 1.ASMCMD文件所在的位置 [root@oradb ~]# su - oracle [oracle@oradb ~]$ which

iBATIS分页实例中ObjectDataSource的应用浅析

iBATIS分页实例中ObjectDataSource的应用首先让我们来看看属性方面的特点,ObjectDataSource 控件内置了对分页的支持.我们需要设置 ObjectDataSource 的 EnablePaging属性,然后要设置SelectMethod.SelectCountMethod .StartRowIndexParameterName和MaximumRowsParameterName 属性.当 EnablePaging 属性设置为 true 时,SelectParamete

故障诊断学习工具:在实践中学习WebSphere应用服务器故障诊断

引言 WebSphere 应用服务的故障诊断一直是客户最为关心的问题之一.为了对 WebSphere 应用 服务器进行快速的问题诊断, IBM 提供了广泛的支持,包括帮助客户进行快速的数据采集,指 导客户进行数据分析以及提供大量的参考手册和技术文档等,这些努力大大减轻了问题诊断的 工作量.然而,问题的解决最终还是要依赖于用户对具体问题的分析.这就像是医生给病人看 病,任何先进的医疗器械和理论知识都代替不了医生的诊断,为了给病人治病,医生不仅要有 扎实的理论基础,还要有丰富的实践经验,对 WebS

这里我们可以看到:Person是个多层次对象,包含多层嵌入属性对象(multi-layer embeded objects)。如果需要更改Person类型实例中的任何字段时,我们可以直接用行令方式(imperative style):

  scala中的case class是一种特殊的对象:由编译器(compiler)自动生成字段的getter和setter.如下面的例子: 1 case class City(name:String, province: String) 2 case class Address(street: String, zip: String, city: City) 3 case class Person(name: String, age: Int, phone: String, address: