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键控制轮廓收缩

  • 相关阅读:
    [php]php时间戳当中关于时区的问题
    [jQuery] jQuery如何获取同一个类标签的所有的值
    sed 命令基础
    Docker 学习第6课
    Docker 学习第五课
    Docker 学习第四课
    Docker 学习第三课
    Docker 学习第二课
    Docker学习第一课
    XdeBug的使用
  • 原文地址:https://www.cnblogs.com/gaohai/p/5788850.html
Copyright © 2011-2022 走看看