• opencv FillEdgeCollection


    opencv  FillEdgeCollection

    static void  FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
    {
        PolyEdge tmp;
        int i, y, total = (int)edges.size();
        Size size = img.size();
        PolyEdge* e;
        int y_max = INT_MIN, y_min = INT_MAX;
        int64 x_max = 0xFFFFFFFFFFFFFFFF, x_min = 0x7FFFFFFFFFFFFFFF;
        int pix_size = (int)img.elemSize();
    
        if( total < 2 )
            return;
    
        for( i = 0; i < total; i++ )
        {
            PolyEdge& e1 = edges[i];
            assert( e1.y0 < e1.y1 );
            // Determine x-coordinate of the end of the edge.
            // (This is not necessary x-coordinate of any vertex in the array.)
            int64 x1 = e1.x + (e1.y1 - e1.y0) * e1.dx;
            y_min = std::min( y_min, e1.y0 );
            y_max = std::max( y_max, e1.y1 );
            x_min = std::min( x_min, e1.x );
            x_max = std::max( x_max, e1.x );
            x_min = std::min( x_min, x1 );
            x_max = std::max( x_max, x1 );
        }
    
        if( y_max < 0 || y_min >= size.height || x_max < 0 || x_min >= ((int64)size.width<<XY_SHIFT) )
            return;
    
        std::sort( edges.begin(), edges.end(), CmpEdges() );
    
        // start drawing
        tmp.y0 = INT_MAX;
        edges.push_back(tmp); // after this point we do not add
                              // any elements to edges, thus we can use pointers
        i = 0;
        tmp.next = 0;
        e = &edges[i];
        y_max = MIN( y_max, size.height );
    
        for( y = e->y0; y < y_max; y++ )
        {
            PolyEdge *last, *prelast, *keep_prelast;
            int sort_flag = 0;
            int draw = 0;
            int clipline = y < 0;
    
            prelast = &tmp;
            last = tmp.next;
            while( last || e->y0 == y )
            {
                if( last && last->y1 == y )
                {
                    // exclude edge if y reaches its lower point
                    prelast->next = last->next;
                    last = last->next;
                    continue;
                }
                keep_prelast = prelast;
                if( last && (e->y0 > y || last->x < e->x) )
                {
                    // go to the next edge in active list
                    prelast = last;
                    last = last->next;
                }
                else if( i < total )
                {
                    // insert new edge into active list if y reaches its upper point
                    prelast->next = e;
                    e->next = last;
                    prelast = e;
                    e = &edges[++i];
                }
                else
                    break;
    
                if( draw )
                {
                    if( !clipline )
                    {
                        // convert x's from fixed-point to image coordinates
                        uchar *timg = img.ptr(y);
                        int x1, x2;
    
                        if (keep_prelast->x > prelast->x)
                        {
                            x1 = (int)((prelast->x + XY_ONE - 1) >> XY_SHIFT);
                            x2 = (int)(keep_prelast->x >> XY_SHIFT);
                        }
                        else
                        {
                            x1 = (int)((keep_prelast->x + XY_ONE - 1) >> XY_SHIFT);
                            x2 = (int)(prelast->x >> XY_SHIFT);
                        }
    
                        // clip and draw the line
                        if( x1 < size.width && x2 >= 0 )
                        {
                            if( x1 < 0 )
                                x1 = 0;
                            if( x2 >= size.width )
                                x2 = size.width - 1;
                            ICV_HLINE( timg, x1, x2, color, pix_size );
                        }
                    }
                    keep_prelast->x += keep_prelast->dx;
                    prelast->x += prelast->dx;
                }
                draw ^= 1;
            }
    
            // sort edges (using bubble sort)
            keep_prelast = 0;
    
            do
            {
                prelast = &tmp;
                last = tmp.next;
    
                while( last != keep_prelast && last->next != 0 )
                {
                    PolyEdge *te = last->next;
    
                    // swap edges
                    if( last->x > te->x )
                    {
                        prelast->next = te;
                        last->next = te->next;
                        te->next = last;
                        prelast = te;
                        sort_flag = 1;
                    }
                    else
                    {
                        prelast = last;
                        last = te;
                    }
                }
                keep_prelast = prelast;
            }
            while( sort_flag && keep_prelast != tmp.next && keep_prelast != &tmp );
        }
    }

    代码来自:opencv-mastermodulesimgprocsrcdrawing.cpp

    ##########################################

    QQ 3087438119
  • 相关阅读:
    ES6常用新特性
    jquery基础总结 -- 转载
    正则验证
    prop attr 到底哪里不一样?
    分页导航 获取当前页码 的 分页导航哦
    使用Bootatrap的心得
    使用padding来合理布局自己的容器类
    使用angular-ui-router替代ng-router
    使用jitpack来获取github上的开源项目
    关于移动端的UI事件分类
  • 原文地址:https://www.cnblogs.com/herd/p/15416281.html
Copyright © 2020-2023  润新知