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

时间: 2024-10-13 21:28:36

Via OpenCv Snake算法的相关文章

opencv分水岭算法对图像进行分割

先看效果 说明 使用分水岭算法对图像进行分割,设置一个标记图像能达到比较好的效果,还能防止过度分割. 1.这里首先对阈值化的二值图像进行腐蚀,去掉小的白色区域,得到图像的前景区域.并对前景区域用255白色标记 2.同样对阈值化后的图像进行膨胀,然后再阈值化并取反.得到背景区域.并用128灰度表示 3.将前景和背景叠加在一起在同一幅图像中显示. 4.用标记图和原图,利用opencv的watershed对图像进行分割. 源码 class WatershedSegment{ private: cv::

opencv分水岭算法对图像进行切割

先看效果 说明 使用分水岭算法对图像进行切割,设置一个标记图像能达到比較好的效果,还能防止过度切割. 1.这里首先对阈值化的二值图像进行腐蚀,去掉小的白色区域,得到图像的前景区域.并对前景区域用255白色标记 2.相同对阈值化后的图像进行膨胀,然后再阈值化并取反.得到背景区域. 并用128灰度表示 3.将前景和背景叠加在一起在同一幅图像中显示. 4.用标记图和原图,利用opencv的watershed对图像进行切割. 源代码 class WatershedSegment{ private: cv

OPENCV形态学算法-2

一.漫水填充算法 该算法通过一个指定的种子点,来分析整张图片上的像素,并设置像素差异阈值,在阈值类的点,最后变成相同的颜色.该方法通过上下限和连通方式来达到不同的连通效果. 该方法常用与标记和分离图像的一部分,以便于对其做进一步的分析和处理,填充的结果总是连通的区域. API:void floodFill(源图像,掩码,Point 种子点,scaral 染色值,Rect* 重绘区域的最小边界矩形区域,scaral 与种子点颜色的负差最大值,scaral 与种子点颜色的正差最大值,int 操作方式

opencv 一堆算法,图像处理等

http://blog.csdn.net/wangzhebupt/article/category/1675453 数据挖掘十大经典实用算法及OpenCV算法 http://www.xuebuyuan.com/2178605.html 线性判别分析(Linear Discriminant Analysis, LDA)算法分析 表示看了h 转自  http://blog.csdn.net/warmyellow/article/details/5454943... 2014-08-10 20:06 

OpenMP并行编程应用—加速OpenCV图像拼接算法

OpenMP是一种应用于多处理器程序设计的并行编程处理方案,它提供了对于并行编程的高层抽象.仅仅须要在程序中加入简单的指令,就能够编写高效的并行程序,而不用关心详细的并行实现细节.减少了并行编程的难度和复杂度.也正由于OpenMP的简单易用性,它并不适合于须要复杂的线程间同步和相互排斥的场合. OpenCV中使用Sift或者Surf特征进行图像拼接的算法.须要分别对两幅或多幅图像进行特征提取和特征描写叙述,之后再进行图像特征点的配对.图像变换等操作.不同图像的特征提取和描写叙述的工作是整个过程中

opencv 求算法执行时间的方法

double t = (double)cvGetTickCount(); ProcessOneSample(); // 算法函数 t = (double)cvGetTickCount() - t;//相减为算法执行的时间 printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );

OpenCV+KMeans算法

<span style="font-size:18px;">#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main(int argc, char** argv) { #define MAX_CLUSTERS 5 CvScalar color_table[MAX_CLUSTERS]; IplImage* img

OpenCV——分水岭算法

分水岭算法,是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而集水盆的边界则形成分水岭. 一般的分水岭算法会对微弱边缘,图像中的噪声,物体表面细微的灰度变化造成过度的分割. 以下为分水岭算法的示例程序. watershedSegmenter.h #if !defined WATERSHS #define WATERSHS #include <opencv2/core/core

OpenCv sift算法 图像特征匹配

基于OpenCv 2.4.6 1 #include "highgui.h" 2 3 //#include "features2d/features2d.hpp"// 4 #include <opencv2/nonfree/features2d.hpp> 5 #include<opencv2/legacy/legacy.hpp> 6 #include <iostream> 7 using namespace std; 8 using