OpenCV 实现分水岭算法

种子点的标记没有太搞懂,这个算法的速度还是很快的

 

 

// watershed_test20140801.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

//
// ch9_watershed image
//   This is an exact copy of the watershed.cpp demo in the OpenCV ../samples/c directory
//
// Think about using a morphologically eroded forground and background segmented image as the template
// for the watershed algorithm to segment objects by color and edges for collecting
//
/* *************** License:**************************
   Oct. 3, 2008
   Right to use this code in any way you want without warrenty, support or any guarentee of it working.

   BOOK: It would be nice if you cited it:
   Learning OpenCV: Computer Vision with the OpenCV Library
     by Gary Bradski and Adrian Kaehler
     Published by O'Reilly Media, October 3, 2008

   AVAILABLE AT:
     http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134
     Or: http://oreilly.com/catalog/9780596516130/
     ISBN-10: 0596516134 or: ISBN-13: 978-0596516130    

   OTHER OPENCV SITES:
   * The source code is on sourceforge at:
     http://sourceforge.net/projects/opencvlibrary/
   * The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back):
     http://opencvlibrary.sourceforge.net/
   * An active user group is at:
     http://tech.groups.yahoo.com/group/OpenCV/
   * The minutes of weekly OpenCV development meetings are at:
     http://pr.willowgarage.com/wiki/OpenCV
   ************************************************** */

#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
using namespace cv;

#pragma comment(lib,"opencv_core2410d.lib")
#pragma comment(lib,"opencv_highgui2410d.lib")
#pragma comment(lib,"opencv_imgproc2410d.lib")  

IplImage* marker_mask = 0;
IplImage* markers = 0;
IplImage* img0 = 0, *img = 0, *img_gray = 0, *wshed = 0;
CvPoint prev_pt = {-1,-1};

void on_mouse( int event, int x, int y, int flags, void* param )
{
    if( !img )
        return;

    if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )
        prev_pt = cvPoint(-1,-1);
    else if( event == CV_EVENT_LBUTTONDOWN )
        prev_pt = cvPoint(x,y);
    else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )
    {
        CvPoint pt = cvPoint(x,y);
        if( prev_pt.x < 0 )
            prev_pt = pt;
        cvLine( marker_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );
        cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );
        prev_pt = pt;
        cvShowImage( "image", img );
    }
}

int main( int argc, char** argv )
{
    cout<<"input image name:  "<<endl;
	string file;
	cin>>file;

	char* filename = (char *)file.c_str();

    CvRNG rng = cvRNG(-1);

    if( (img0 = cvLoadImage(filename,1)) == 0 )
        return 0;

    printf( "Hot keys: \n"
            "\tESC - quit the program\n"
            "\tr - restore the original image\n"
            "\tw or ENTER - run watershed algorithm\n"
            "\t\t(before running it, roughly mark the areas on the image)\n"
            "\t  (before that, roughly outline several markers on the image)\n" );

    cvNamedWindow( "image", 1 );
    cvNamedWindow( "watershed transform", 1 );

    img = cvCloneImage( img0 );
    img_gray = cvCloneImage( img0 );
    wshed = cvCloneImage( img0 );
    marker_mask = cvCreateImage( cvGetSize(img), 8, 1 );
    markers = cvCreateImage( cvGetSize(img), IPL_DEPTH_32S, 1 );
    cvCvtColor( img, marker_mask, CV_BGR2GRAY );
    cvCvtColor( marker_mask, img_gray, CV_GRAY2BGR );

    cvZero( marker_mask );
    cvZero( wshed );
    cvShowImage( "image", img );
    cvShowImage( "watershed transform", wshed );
    cvSetMouseCallback( "image", on_mouse, 0 );

    for(;;)
    {
        int c = cvWaitKey(0);

        if( (char)c == 27 )
            break;

        if( (char)c == 'r' )
        {
            cvZero( marker_mask );
            cvCopy( img0, img );
            cvShowImage( "image", img );
        }

        if( (char)c == 'w' || (char)c == '\n' )
        {
            CvMemStorage* storage = cvCreateMemStorage(0);
            CvSeq* contours = 0;
            CvMat* color_tab;
            int i, j, comp_count = 0;
            //cvSaveImage( "wshed_mask.png", marker_mask );
            //marker_mask = cvLoadImage( "wshed_mask.png", 0 );
            cvFindContours( marker_mask, storage, &contours, sizeof(CvContour),
                            CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
            cvZero( markers );
            for( ; contours != 0; contours = contours->h_next, comp_count++ )
            {
                cvDrawContours( markers, contours, cvScalarAll(comp_count+1),
                                cvScalarAll(comp_count+1), -1, -1, 8, cvPoint(0,0) );
            }

            color_tab = cvCreateMat( 1, comp_count, CV_8UC3 );
            for( i = 0; i < comp_count; i++ )
            {
                uchar* ptr = color_tab->data.ptr + i*3;
                ptr[0] = (uchar)(cvRandInt(&rng)%180 + 50);
                ptr[1] = (uchar)(cvRandInt(&rng)%180 + 50);
                ptr[2] = (uchar)(cvRandInt(&rng)%180 + 50);
            }

            {
            double t = (double)cvGetTickCount();
            cvWatershed( img0, markers );
            t = (double)cvGetTickCount() - t;
            printf( "exec time = %gms\n", t/(cvGetTickFrequency()*1000.) );
            }

            // paint the watershed image
            for( i = 0; i < markers->height; i++ )
                for( j = 0; j < markers->width; j++ )
                {
                    int idx = CV_IMAGE_ELEM( markers, int, i, j );
                    uchar* dst = &CV_IMAGE_ELEM( wshed, uchar, i, j*3 );
                    if( idx == -1 )
                        dst[0] = dst[1] = dst[2] = (uchar)255;
                    else if( idx <= 0 || idx > comp_count )
                        dst[0] = dst[1] = dst[2] = (uchar)0; // should not get here
                    else
                    {
                        uchar* ptr = color_tab->data.ptr + (idx-1)*3;
                        dst[0] = ptr[0]; dst[1] = ptr[1]; dst[2] = ptr[2];
                    }
                }

            cvAddWeighted( wshed, 0.5, img_gray, 0.5, 0, wshed );
            cvShowImage( "watershed transform", wshed );
            cvReleaseMemStorage( &storage );
            cvReleaseMat( &color_tab );
        }
    }

    return 1;
}

 

 

 

实现效果:

 

 

 

时间: 2024-11-02 17:57:52

OpenCV 实现分水岭算法的相关文章

OpenCV学习(9) 分水岭算法(3)

本教程我学习一下opencv中分水岭算法的具体实现方式. 原始图像和Mark图像,它们的大小都是32*32,分水岭算法的结果是得到两个连通域的轮廓图. 原始图像:(原始图像必须是3通道图像) Mark图像: 结果图像:       初始的mark图像数据如下,黄色的部分为我们的第一个mark区域,值为255,第二个区域为褐红色的区域,值为128,第三个绿色的区域,值为64.   opencv分水岭算法描述如下: 初始化mark矩阵,生成最初的注水区域. 1.设置mark图像的边框值为-1 2.

OpenCV学习(8) 分水岭算法(2)

    现在我们看看OpenCV中如何使用分水岭算法.     首先我们打开一副图像:    // 打开另一幅图像   cv::Mat    image= cv::imread("../tower.jpg");     if (!image.data)         {         cout<<"不能打开图像!"<<endl;         return 0;         }      接下来,我们要创建mark图像.mark图像

版主您好,关于您的Opencv3书本的分水岭算法的分析,第337页的标记目标图有个不明确地方请教下

问题描述 版主您好,关于您的Opencv3书本的分水岭算法的分析,第337页的标记目标图有个不明确地方请教下 请问个问题,关于您的书Opencv3第337页的line(g__maskimage为什么不可以改成line(maskimage也就是直接把分水岭种子布在结果图上,而要多一个中间掩膜图步骤然后还要再寻找轮廓和绘制轮廓?直接花在结果图maskimage上,不就省了_从g_maskimage上findcontours()再drawcontours(0到maskimage这个过程了吗? 解决方案

图片-分水岭算法分割之后的特征提取

问题描述 分水岭算法分割之后的特征提取 用分水岭算法把一张彩色图片分割成了这样,目标是检测出里面的猪,请问当下用什么特征提取比较好,我是新手请多指教~

OpenCV 1 图像分割--分水岭算法代码

// watershed_test20140801.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" // // ch9_watershed image // This is an exact copy of the watershed.cpp demo in the OpenCV ../samples/c directory // // Think about using a morphologically eroded forground an

OpenCV特征点检测算法对比

识别算法概述: SIFT/SURF基于灰度图, 一.首先建立图像金字塔,形成三维的图像空间,通过Hessian矩阵获取每一层的局部极大值,然后进行在极值点周围26个点进行NMS,从而得到粗略的特征点,再使用二次插值法得到精确特征点所在的层(尺度),即完成了尺度不变.   二.在特征点选取一个与尺度相应的邻域,求出主方向,其中SIFT采用在一个正方形邻域内统计所有点的梯度方向,找到占80%以上的方向作为主方向:而SURF则选择圆形邻域,并且使用活动扇形的方法求出特征点主方向,以主方向对齐即完成旋转

计算机视觉 图像处理-相似图像分割算法实现

问题描述 相似图像分割算法实现 如下:两块材料一样,颜色一样的布料,如何用算法分割开?,canny算法和一些一般梯度算法都不能的到好的结果.计算机视觉 图像处理-相似图像分割算法实现-图像分割 计算机视觉"> 解决方案 用分水岭算法实现图像分割 (祝勇)图片像素对比OpenCV实现,实现人工分割跟算法分割图像结果的对比基于GraphCuts图割算法的图像分割----OpenCV代码与实现 解决方案二: 这需要比较专业的算法才能识别吧 至少要先提取给关键点,然后根据关键点是否相同的区分.因为

图像处理-opencv新手入门方法介绍

问题描述 opencv新手入门方法介绍 本人大二,刚刚接触科研方面内容,想入门opencv图像处理技术,但是由于接触的还不多,c++也处于入门级水平,一些opencv里面的算法都不怎么看得懂数学原理,现在不知道是怎么入门,望高人指教 解决方案 你最好还是把C++的基础弄扎实一点,然后推荐一本书,<学习OpenCv中文版>个人觉得还是挺不错的,是C语言写的.然后边看书边在csdn上找一些相关的博客 解决方案二: opencv是一个计算机视觉库,包含很多图像处理和计算机视觉方面的通用算法,所以学习

OpenCV特征点检测------Surf(特征点篇)

Surf(Speed Up Robust Feature) Surf算法的原理                                                                           1.构建Hessian矩阵构造高斯金字塔尺度空间 其实surf构造的金字塔图像与sift有很大不同,就是因为这些不同才加快了其检测的速度.Sift采用的是DOG图像,而surf采用的是Hessian矩阵行列式近似值图像.Hessian矩阵是Surf算法的核心,为了方便运算