zoukankan      html  css  js  c++  java
  • Via OpenCv Snake算法

    /*
    * 代码功能:手动选定初始边缘,使用cvSnakeImage算法迭代寻优
    * 修改:jink2005 2009-11-18
    * 论坛:http://www.aiseminar.cn/bbs
    */
    #include "cv.h"
    #include "highgui.h"
    #include <iostream>
    #include <vector>
    #include <opencv2/legacy/legacy.hpp>
    //#pragma comment(lib, "highgui.lib")
    //#pragma comment(lib, "cv.lib")
    //#pragma comment(lib, "cvaux.lib")
    //#pragma comment(lib, "cxcore.lib")
    std::vector<CvPoint> InitContour;
    IplImage* temp;  //= cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
    /*
    * 使用直线连接轮廓点,绘制轮廓线的函数
    */
    void showContent(IplImage * img)
    {
        if(temp == NULL)
            temp = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
        cvCopyImage(img, temp);
        for (int i = 0; i < InitContour.size(); i++)
        {
            cvCircle(temp, InitContour[i], 2, cvScalarAll(155));
            if(i > 0)
                cvLine(temp, InitContour[i-1], InitContour[i], cvScalarAll(100), 1);
        }
        cvShowImage("srcImage", temp);
    }
    void on_mouse(int event, int x, int y, int flags, void* ptr)
    {
        if(event == CV_EVENT_LBUTTONDOWN)
        {
            InitContour.push_back(cvPoint(x,y));
            /*InitContour.push_back(cvPoint(130,130));
            for(int i=130;i<660;i=i+10)
            {
                InitContour.push_back(cvPoint(i,130));
            }
        
            for(int i=130;i<660;i=i+20)
            {
                InitContour.push_back(cvPoint(660,i));
            }
            
            for(int i=660;i>130;i=i-10)
            {
                InitContour.push_back(cvPoint(i,660));
            }
            
            for(int i=660;i>130;i=i-20)
            {
                InitContour.push_back(cvPoint(130,i));
            }
            InitContour.push_back(cvPoint(130,130));*/
        
        
        
            
            
            showContent((IplImage *)ptr);
        }
    }
    int main(int argc, char* argv[])
    {
        IplImage * srcimage = NULL;
        if (argc == 2 && (srcimage = cvLoadImage((char *)argv[1], CV_LOAD_IMAGE_GRAYSCALE)) !=0)
            ;
        else //载入工作目录下文件名为apple.jpg的图片。
        {
            srcimage = cvLoadImage("test1.jpg", CV_LOAD_IMAGE_GRAYSCALE);   
        }
        if(srcimage == NULL)
        {
            std::cout << "Can't find the image file!" << std::endl;
            return -1;
        }
        InitContour.clear();
        cvNamedWindow("srcImage");
        cvShowImage("srcImage", srcimage);
        cvSetMouseCallback("srcImage", on_mouse, srcimage);
        char c;
        while(char c = cvWaitKey(0))
            if(c == 's' || c == 'S')
                break;
        // 设置snake算法使用的参数
        float alpha = 1.0;
        float beta = 0.5;
        float gamma = 1.0;
        CvSize size;
        size.width = 3;
        size.height = 3;
        CvTermCriteria criteria;
        criteria.type = CV_TERMCRIT_ITER;
        criteria.max_iter = 500;
        criteria.epsilon = 0.1;
        int itetime = 100;
        for(int ite = 0; ite < itetime; ite++) // cvSnakeImage自己有循环,为什么这里还要?手动控制循环次数!
        {
            CvPoint*  pts = new CvPoint[InitContour.size()];
            for (int i = 0; i < InitContour.size(); i++)
            {
                pts[i] = InitContour[i];
            }
            // 使用snake算法来修改轮廓
            cvSnakeImage(srcimage, pts, InitContour.size(), &alpha, &beta, &gamma, CV_VALUE, size, criteria, 1);
            int size = InitContour.size();
            // 清空原轮廓,更新为新的轮廓点
            InitContour.clear();
            for (int i = 0; i < size; i++)
            {
                InitContour.push_back(pts[i]);
                // 对轮廓点进行线性插值,插入中间点
                int next = (i + 1) % size;
                CvPoint ne = pts[next];
                if(size < 100)
                {
                    CvPoint mid = cvPoint((pts[i].x + ne.x) / 2, (pts[i].y + ne.y) / 2);
                    InitContour.push_back(mid);
                }
            }
            delete []pts;
            showContent(srcimage);
            cvWaitKey(); // 手动控制增加迭代次数,按任意键
        }
        showContent(srcimage);
        cvWaitKey();
        return 0;}
    Snake

    鼠标左键画好轮廓后,S键控制轮廓收缩

  • 相关阅读:
    bzoj-2748 2748: [HAOI2012]音量调节(dp)
    bzoj-2338 2338: [HNOI2011]数矩形(计算几何)
    bzoj-3444 3444: 最后的晚餐(组合数学)
    codeforces 709E E. Centroids(树形dp)
    codeforces 709D D. Recover the String(构造)
    codeforces 709C C. Letters Cyclic Shift(贪心)
    codeforces 709B B. Checkpoints(水题)
    codeforces 709A A. Juicer(水题)
    Repeat Number
    hdu 1003 Max Sum (动态规划)
  • 原文地址:https://www.cnblogs.com/gaohai/p/5788850.html
Copyright © 2011-2022 走看看