在介绍图像处理和机器视觉算法之前,有必要对一些基础对象进行说明。这些基础对象为最基本的数据结构,在后续的模块里面可能会被使用到。是一些功能模块的基础。
动态数据操作对象的数据有多种数据类型。但是不管什么数据类型,只能都只能通过变量引用的方式进行添加或修改。如:
int n=20;rsqAddLast(sequence, &n);
动态数据操作对象遵循创建/销毁模式。为了加快数据操作速度,序列和聚合对象有专门的宏进行数据读写操作。
序列比较常用的动态数据结构。序列可用用在很多场所。如作为先进后出栈,先进先出队。在使用序列之前,通常需要创建:
RvSequence seq = rvCreateSequence(RDT_INT);
创建序列的时候,需要指定元素的数据类型。
当序列创建成功以后,可以将新的数据添加到序列头部或序列尾部。如:
int n=12;rsqAppend(seq, &n);
也可以插入中间某个位置。如
rsqInsert(seq, 10,&n);
同样,在删除的时候,可以从头部删除或者尾部删除,也可以将某个具体的元素删除如:
HITEM item = rsqSeekToBegin(seq);
rsqRemoveItem(seq, item);
上面的语句将头部的元素对象获取到,然后,进行删除。有时候,可能用户需要将序列中元素值等于某个具体的值删除(可能同时删除若干个元素),如:
n=1;
rsqRemoveElem(seq, &n);
这些语句将元素值等于1的所有元素删除。当然,也可以无条件地将序列中所有的元素全部清除,如:
rsqClear(seq);
可以对序列中的元素按照位置进行索引读取或写入。如下面的语句首先将生成一个包含15个元素的序列,然后,按照顺序将每个元素的值设置成新值:
Int total =15;
for (int i=0; i< total; i++){
rsqAppend(seq, &i);
}for (int i=0; i< total; i++){
n = i+100;
rsqSetItemValue(seq,i , &n);}
(TIPS:在使用索引的方式进行元素读写的时候,一定要确保序列里面存在已经元素节点。)如果要对元素进行索引方式读取,可以按照下面的方式进行:
for (int i=0; i< rsqGetCount(seq); i++){rsqGetItemValue(seq, i, &n);
sprintf("%d, ", n);
}使用快速操作方式,可以明显提高应用程序的效率。快速操作主要用在某个函数全部为读或全部为写的情况,主要按照顺序方式进行。如:
RvSeqWriter sw;
RV_BEGIN_WRITE_SEQ(seq, &sw);
for (int i=0; i< total; i++){n = i+100;
RV_WRITE_TO_SEQ_EX(&sw, &n, TRUE);
} RV_END_WRITE_SEQ(seq, &sw);上面的语句,按照顺序写入若干个元素。
如果要顺序读取某一个序列的所有元素,可以按照下面的方式进行。
RvSeqReader sr;
RV_BEGIN_READ_SEQ(seq, &sr);
while(!RV_IS_SEQ_END(&sr)){RV_READ_FR_SEQ(&sr, &n);
sprintf("%d, ", n);}
RV_END_READ_SEQ(seq, &sr);序列作为队数据结构,也可以使用快速方式进行入对或出队工作:
RvSeqWriter sw;
RV_BEGIN_QUEUE(seq, &sw);
for (int i=0; i< total; i++){
n = i+100;
RV_PUSH_TO_QUEUE(&sw,&n);}
RV_END_QUEUE(seq, &sw);
出队的典型方式如下:
while(!RV_IS_QUEUE_EMPTY(&sw)){
RV_POP_FROM_QUEUE(&sw,&n);
sprintf("%d, ", n);}
(TIPS:快速操作仅适合c/c++编程语言)
聚合是同类型数据的集合,在对聚合的操作过程中,不保证数据元素之间的先后顺序。创建聚合与创建序列一样,需要指定元素类型。如:
RvCluster clust = rvCreateCluster(RDT_INT);
元素添加通常在数据集合的末尾。如:Int n=12;
rclAppend(clust, &n);
删除可以通过元素值的方法进行,同时可以删除多个元素(具有相同的值)。
rclRemove(clust, &n);
很多情况下,可能需要将两个聚合的元素合并成到一个集合里面,如:rclMerge(clust, clust1, TRUE);
这个函数将clust1里面的所有元素合并到clust, 同时将clust1里面的元素清空。
for (int i=0; i< total; i++){
rclAppend(clust, &i);
}for (int i=0; i< rclGetCount(clust); i++){
n = rclGetCount(clust)-1 -i;
rclSetAt(clust, i, &n);
}for (int i=0; i< rclGetCount(clust); i++){
n = *((int*)rclGetAt(clust, i));
sprintf ("%d, ", n);
} (TIPS:当聚合操作在进行不断的添加和删除操作以后,用索引的方式进行读写的时候,数据与前面的同一位置的数据可能不一样。)对于聚合来说,里面的数据量一般很大,应用快速读写操作,可以显著提高应用程序的处理性能。下面的语句对聚合写入若干个元素:
RvClusterWriter cw; int n,i; RV_BEGIN_WRITE_CLUST(clust, &cw);for (i =0; i<64; i++){
n=i ;
RV_WRITE_TO_CLUST(&cw, &n);
} RV_END_WRITE_CLUST(clust, &cw);如果要快速读出数据,可以按照下面方式进行:
RvClusterReader cr;
RV_BEGIN_READ_CLUSTER(clust, &cr);
while(TRUE){
if ( RV_IS_CLUST_END(&cr)) break;
RV_READ_FR_CLUSTER(&cr, &n);
sprintf ("%d, ", n);
}RV_END_READ_CLUST(clust, &cr);
当然,也可以使用索引的方式对聚合对象的数据读出。(TIPS:快速操作仅适合c/c++编程语言)
RvList list = rvCreateList();
新的数据可以添加到列表的首尾位置,下面的函数将若干个元素添加到列表首部,即最后插入的数据在列表头部: int total = 15; int* pN; for (int i=0; i< total; i++){pN = new int;
ASSERT(pN);
*pN = i;
rlsAddHead(list, pN);
} 使用完成以后,一般用户需要自己将元素的数据内存释放。如:for (int i=0; i< rlsGetCount(list); i++){
pN = (int*)rlsGetAt(list, i);
sprintf ("%d, ",*pN);
delete pN;
}rlsRemoveAll(list);
这些语句将列表的元素空间释放,同时,清除列表中所有的元素。
列表没有相应的快速读写宏。在需要对元素进行遍历的时候建议按照下面的方式进行,以取得较好的处理性能。
if (rlsGoHead(list)){
while(TRUE){
pN =(int*) rlsGetCur(list);
sprintf ("%d, ",*pN);
if (rlsStep(list) ==FALSE) break;
} } 2.2读数银行对象读数银行对象是保存图像分析的结果的对象,读数对象可以由若干不同类型的数值组成,这些对象已索引值的形式进行访问。银行读数对象用于需要返回多个值的函数,这些值的数据类型可能一样也可能不一样。通常情况下,读数银行在使用之前需要创建,如:
RvReadingBank bank = rvCreateReadingBank();
使用完成以后,进行销毁。
rvDestroyReadingBank(bank);
下面的语句将整数12赋值给索引值为9(索引从0开始)的元素,
rrdSetInteger(bank, 12, 9);
如果索引值小于0,则自动添加一个新的元素到读数银行对象最尾部。
(TIPS: 一般复合型数据类型如RvRgb, RvSize等的元素采用引用传递的方式进行修改或写入,读取的时候全部使用引用的方式进行。一般情况下,如果没有输入读数银行对象,函数会自动生成一个并返回,由函数自动生成的这些读数对象也需要进行显示销毁)。RvMask mask = rvCreateMask(RV_MT_RECT, 128, 100);
这个语句创建一个宽度为128,高度为100的矩形形状的模板。有时候,经过处理后的二元图像也可能被用做模板,这样可以直接使用二元图像的图像数据作为模板矩阵数据。如:RvImage image = rvLoadImage(“mybin.bmp”);
rviCast(image, RIT_BIN);
RvMask mask = rvCreateMaskEx(rviGetWidth(image), rviGetHeight(image), rviGetData(image), rviGetSize(image), rviGetPitch(image));上面的方式创建的mask将不会分配额外的矩阵数据。
(TIPS: 不管用何种方式创建模板,记得使用rvDestroyMask销毁哦。)
抖音视频号: 第一感机器视觉
微信公众号: 精浦科技
深圳市软云动力科技有限公司
东莞办事处: 广东省东莞市松湖智谷B6栋225b
公司地址: 广东省深圳市南山区桃园路金桃园大厦2191
深圳市软云动力科技有限公司 版权所有 鄂ICP备2022015826号-2