opencv创建序列cvCreateSeq与插入元素cvSeqPush的运用

来源:互联网 发布:程序员算法 编辑:程序博客网 时间:2024/05/17 03:12

1)序列在内部其实对应一个双端序列。因此,我们可以高效地从序列的任意一端(开头和结尾)访问序列。这样我们可以很自然地将序列做一个栈使用。与CvSeq结构一起使用,下面六个函数可将序列封装成一个栈(准确来说,是双端队列,因此它们可以两端操作元素)。

char *  cvSeqPush(CvSeq *seq, void *element = NULL);//压栈

char *  cvSeqPushFront(CvSeq *seq,void *element =NULL);

void *  cvSeqPop(CvSeq * seq, void *element=NULL);//出栈

void  cvSeqPushMulti(CvSeq *seq, void *elements, int count, int in_front=0); //多个元素压栈

void cvSeqPopMulti(CvSeq *seq, void *elements, int count, int in_front=0);//多个元素出栈

上面有一个参数用于指定序列的开头还是结尾。可以用宏来表示开头或结尾:

CV_FRONT(1)对应开头。

CV_BACK(0)对应结尾。


2)pow

POW是C/C++中的数学函数。

原型:在TC2.0中原型为extern float pow(float x, float y); ,而在VC6.0中原型为double pow( double x, double y );

头文件:math.h/cmath(C++中)

功能:计算x的y次幂。

返回值:x不能为负数且y为小数,或者x为0且y小于等于0,返回幂指数的结果。

返回类型:double型,int,float会给与警告!


3)cvCreateSeq:创建序列

CvSeq *cvCreateSeq(int seq_flags, int header_size, 

int elem_size, CvMemStorage *storage);

header_size:序列头的大小,通常为sizeof(CvSeq)。

elem_size:存储元素的大小。

storage:内存存储器,添加元素的时候,就会从内存存储器申请空间。

flags:变量可以由3个类值组成。不同类值之间的标志可以用或运算来组合。

第一类确定序列中元素的类型:

CV_SEQ_ELTYPE_POINT--点坐标(x,y)

CV_SEQ_ELTYPE_CODE--Freeman:0..7

CV_SEQ_ELTYPE_PPOINT--指向一个点的指针:&(x,y)

CV_SEQ_ELTYPE_INDEX--点的整数索引:#(x,y)

CV_SEQ_ELTYPE_GRAPH_EDGE--&next_o,&next_d,&vtx_o,&vtx_d

CV_SEQ_ELTYPE_GRAPH_VERTEX--first_edge,&(x,y)

CV_SEQ_ELTYPE_TRIAN_ATR--二叉树的结点

CV_SEQ_ELTYPE_CONNECTED_COMP--联通的区域

CV_SEQ_ELTYPE_POINT3D--三维的点坐标:(x,y,z)

第二类表示序列本身的性质:

CV_SEQ_KIND_SET--元素的集合

CV_SEQ_KIND_CURVE--元素所定义的曲线

CV_SEQ_KIND_BIN_TREE--二叉树

CV_SEQ_KIND_GRAPH--图,其结点为序列内元素

第三类表示序列的其他属性:

CV_SEQ_FLAG_CLOSED--序列是闭合的(多边形)

CV_SEQ_FLAG_SIMPLE--序列是简单的(多边形)

CV_SEQ_FLAG_CONVEX--序列是凸的(多边形)

CV_SEQ_FLAG_HOLE--序列是一个嵌套的(多边形)


代码:

#include<string>
#include <cv.h>

#include <highgui.h>

#include <iostream>
#include <opencv2/legacy/legacy.hpp>
#include <cmath>
using namespace cv;
using namespace std;
int main()
{
    CvMemStorage *sotrage = cvCreateMemStorage();
    int flags = CV_SEQ_ELTYPE_POINT | CV_SEQ_FLAG_CLOSED;
    CvSeq * seq_circle = cvCreateSeq(flags, sizeof(CvSeq), sizeof(CvPoint), sotrage);
    IplImage * image_circle = cvCreateImage(cvSize(300, 300), IPL_DEPTH_8U, 1);//创建300*300大小的图
    cvZero(image_circle);

    int center_x = 150;//确定圆的中心坐标为(150,150)
    int center_y = 150;
    int r = 100;        //确定圆的半径为100
    int x_temp, y_temp;
//算法有点复杂
    for (int x = 20; x <= 300; ++x)
    {
        for (int y = 20; y <= 300; ++y)
        {
//不断循环搜索与中心点之间的距离满足圆方程的坐标点
            if (x < center_x)
            {
                x_temp = center_x - x;
            }
            else
            {
                x_temp = x - center_x;
            }
            if (y < center_y)
            {
                y_temp = center_y - y;
            }
            else
            {
                y_temp = y - center_y;
            }
//原型为double pow( double x, double y );计算x的y次幂。
            if (x_temp*x_temp+y_temp*y_temp==r*r  )//pow(x_temp,2) + pow(y_temp, 2)) == pow(r, 2)
            {
                CvPoint pt;
                pt.x = x;
                pt.y = y;
                cvSeqPush(seq_circle, &pt);//往序列里压元素pt
                //cvSetReal2D(image_circle, pt.x, pt.y, 255);
            }
        }
    }
    for (int i = 0; i < seq_circle->total; ++i)
    {
        CvPoint * pt = (CvPoint*)cvGetSeqElem(seq_circle, i);
        cvSetReal2D(image_circle, pt->x, pt->y, 255);//把指定的点设置为黑色的点
    }
    cvNamedWindow("图像", CV_WINDOW_AUTOSIZE);
    cvShowImage("图像",image_circle);
cvSaveImage("result.jpg",image_circle);
    cvWaitKey(0);
    cvReleaseImage(&image_circle);
    cvDestroyAllWindows();
    return 0;
}

结果:






0 0
原创粉丝点击