SLIC超像素分割算法和目前超像素算法的比较代码实现 - 图文

更新时间:2023-09-23 16:52:01 阅读量: IT计算机 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Resource.h

//{{NO_DEPENDENCIES}}

// Microsoft Visual C++ generated include file. // Used by SLICSuperpixels.rc //

#define IDD_SLICSUPERPIXELS_DIALOG 102 #define IDR_MAINFRAME 128 #define IDC_BUTTON_CREATESUPERPIXELS 1000 #define IDC_EDIT_SPCOUNT 1001 #define IDC_EDIT2 1002 #define IDC_EDIT_COMPACTNESS 1002

// Next default values for new objects //

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE 129 #define _APS_NEXT_COMMAND_VALUE 32771 #define _APS_NEXT_CONTROL_VALUE 1003 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif

Stdafx.h

// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, // but are changed infrequently

#pragma once

#ifndef _SECURE_ATL #define _SECURE_ATL 1 #endif

#ifndef VC_EXTRALEAN

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #endif

#include \

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit

// turns off MFC's hiding of some common and often safely ignored warning messages #define _AFX_ALL_WARNINGS

#include // MFC core and standard components #include // MFC extensions

#ifndef _AFX_NO_OLE_SUPPORT

#include // MFC support for Internet Explorer 4 Common Controls #endif

#ifndef _AFX_NO_AFXCMN_SUPPORT

#include // MFC support for Windows Common Controls #endif // _AFX_NO_AFXCMN_SUPPORT

#include // MFC support for ribbons and control bars

SLIC.h

// SLIC.h: interface for the SLIC class.

//=========================================================================== // This code implements the superpixel method described in: //

// Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi, Pascal Fua, and Sabine Susstrunk,

// \

// EPFL Technical Report no. 149300, June 2010.

//=========================================================================== // Copyright (c) 2012 Radhakrishna Achanta [EPFL]. All rights reserved. //=========================================================================== //////////////////////////////////////////////////////////////////////

#if !defined(_SLIC_H_INCLUDED_) #define _SLIC_H_INCLUDED_

#include #include #include using namespace std;

class SLIC { public:

SLIC();

virtual ~SLIC();

//============================================================================ // Superpixel segmentation for a given step size (superpixel size ~= step*step) //============================================================================

void DoSuperpixelSegmentation_ForGivenSuperpixelSize(

const unsigned int* ubuff,//Each 32 bit unsigned int contains ARGB pixel values.

const int const int int*& int&

width, height, klabels,

superpixelsize,

numlabels,

const int&

const double& compactness);

//============================================================================ // Superpixel segmentation for a given number of superpixels

//============================================================================

void DoSuperpixelSegmentation_ForGivenNumberOfSuperpixels( const unsigned int* ubuff,

const int const int int*& int&

width, height, klabels,

K,//required number of superpixels

numlabels,

const int& good value for CIELAB space

const double& compactness);//10-20 is a

//============================================================================ // Supervoxel segmentation for a given step size (supervoxel size ~= step*step*step) //============================================================================ void DoSupervoxelSegmentation(

unsigned int**&

ubuffvec,

const int& const int& const int& int**& int&

width, height, depth, klabels,

supervoxelsize,

numlabels,

const int&

private:

const double& compactness);

//============================================================================ // Save superpixel labels in a text file in raster scan order

//============================================================================ void SaveSuperpixelLabels(

const int*& const int& const int&

labels, width, height,

const string& const string&

filename, path);

//============================================================================ // Save supervoxel labels in a text file in raster scan, depth order

//============================================================================ void SaveSupervoxelLabels(

const int**& const int& const int& const int&

labels,

width, height, depth,

const string& const string&

filename, path);

//============================================================================ // Function to draw boundaries around superpixels of a given 'color'.

// Can also be used to draw boundaries around supervoxels, i.e layer by layer. //============================================================================ void DrawContoursAroundSegments(

unsigned int*& int*&

const int& const int&

segmentedImage, labels, width, height, color );

const unsigned int&

//============================================================================ // The main SLIC algorithm for generating superpixels

//============================================================================

void PerformSuperpixelSLIC(

vector& vector& vector& vector& vector& int*&

const int&

kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, klabels, STEP,

edgemag,

const vector&

const double&

m = 10.0);

//============================================================================ // The main SLIC algorithm for generating supervoxels

//============================================================================ void PerformSupervoxelSLIC(

vector& vector& vector& vector& vector& vector& int**& const int&

kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, kseedsz, klabels, STEP,

const double& compactness);

//============================================================================ // Pick seeds for superpixels when step size of superpixels is given.

//============================================================================ void GetLABXYSeeds_ForGivenStepSize(

vector& vector& vector& vector& vector& const int&

const bool&

kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, STEP,

perturbseeds,

const vector& edgemag);

//============================================================================ // Pick seeds for supervoxels

//============================================================================ void GetKValues_LABXYZ(

vector& vector&

kseedsl, kseedsa,

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

SLIC::SLIC() { }

SLIC::~SLIC() { }

//============================================================================== /// RGB2XYZ ///

if(m_lvecvec) { }

if(m_avecvec) { }

if(m_bvecvec) { }

for( int d = 0; d < m_depth; d++ ) delete [] m_bvecvec[d]; delete [] m_bvecvec;

for( int d = 0; d < m_depth; d++ ) delete [] m_avecvec[d]; delete [] m_avecvec;

for( int d = 0; d < m_depth; d++ ) delete [] m_lvecvec[d]; delete [] m_lvecvec; if(m_lvec) delete [] m_lvec; if(m_avec) delete [] m_avec; if(m_bvec) delete [] m_bvec; m_lvecvec = NULL; m_avecvec = NULL; m_bvecvec = NULL; m_lvec = NULL; m_avec = NULL; m_bvec = NULL;

/// sRGB (D65 illuninant assumption) to XYZ conversion

//============================================================================== void SLIC::RGB2XYZ( { }

//=========================================================================== /// RGB2LAB

//===========================================================================

void SLIC::RGB2LAB(const int& sR, const int& sG, const int& sB, double& lval, double& aval, double& bval) {

//------------------------ //------------------------ // sRGB to XYZ conversion //------------------------ double X, Y, Z;

RGB2XYZ(sR, sG, sB, X, Y, Z);

X = r*0.4124564 + g*0.3575761 + b*0.1804375; Y = r*0.2126729 + g*0.7151522 + b*0.0721750; Z = r*0.0193339 + g*0.1191920 + b*0.9503041; if(R <= 0.04045) r = R/12.92; else else else

r = pow((R+0.055)/1.055,2.4); g = pow((G+0.055)/1.055,2.4); b = pow((B+0.055)/1.055,2.4);

if(G <= 0.04045) g = G/12.92; if(B <= 0.04045) b = B/12.92; double r, g, b; double R = sR/255.0; double G = sG/255.0; double B = sB/255.0; const int& const int& const int& double& double& double&

sR, sG, sB, X, Y, Z)

}

// XYZ to LAB conversion //------------------------

double epsilon = 0.008856; //actual CIE standard double kappa = 903.3;

//actual CIE standard

double Xr = 0.950456; //reference white double Yr = 1.0;

//reference white

double Zr = 1.088754; //reference white double xr = X/Xr; double yr = Y/Yr; double zr = Z/Zr; double fx, fy, fz;

if(xr > epsilon) fx = pow(xr, 1.0/3.0); else else else

fx = (kappa*xr + 16.0)/116.0; fy = (kappa*yr + 16.0)/116.0; fz = (kappa*zr + 16.0)/116.0;

if(yr > epsilon) fy = pow(yr, 1.0/3.0); if(zr > epsilon) fz = pow(zr, 1.0/3.0);

lval = 116.0*fy-16.0; aval = 500.0*(fx-fy); bval = 200.0*(fy-fz);

//=========================================================================== /// DoRGBtoLABConversion ///

/// For whole image: overlaoded floating point version

//=========================================================================== void SLIC::DoRGBtoLABConversion( {

int sz = m_width*m_height; lvec = new double[sz]; avec = new double[sz]; bvec = new double[sz]; const unsigned int*& double*& double*& double*&

ubuff, lvec, avec, bvec)

}

//=========================================================================== /// DoRGBtoLABConversion ///

/// For whole volume

//=========================================================================== void SLIC::DoRGBtoLABConversion( { }

//================================================================================= /// DrawContoursAroundSegments ///

/// Internal contour drawing option exists. One only needs to comment the if /// statement inside the loop that looks at neighbourhood.

}

}

RGB2LAB( r, g, b, lvec[d][j], avec[d][j], bvec[d][j] );

int sz = m_width*m_height; for( int d = 0; d < m_depth; d++ ) {

for( int j = 0; j < sz; j++ ) {

int r = (ubuff[d][j] >> 16) & 0xFF; int g = (ubuff[d][j] >> 8) & 0xFF; int b = (ubuff[d][j] ) & 0xFF;

unsigned int**& double**& double**& double**&

ubuff,

lvec, avec, bvec)

}

RGB2LAB( r, g, b, lvec[j], avec[j], bvec[j] ); for( int j = 0; j < sz; j++ ) {

int r = (ubuff[j] >> 16) & 0xFF; int g = (ubuff[j] >> 8) & 0xFF; int b = (ubuff[j] ) & 0xFF;

//================================================================================= void SLIC::DrawContoursAroundSegments( {

/* int sz = width*height;

}

if( np > 1 )//change to 2 or 3 for thinner lines { }

ubuff[mainindex] = color; istaken[mainindex] = true; }

if( false == istaken[index] )//comment this to obtain internal contours { }

if( labels[mainindex] != labels[index] ) np++;

if( (x >= 0 && x < width) && (y >= 0 && y < height) ) {

int index = y*width + x;

int mainindex(0);

for( int j = 0; j < height; j++ ) {

for( int k = 0; k < width; k++ ) {

int np(0);

for( int i = 0; i < 8; i++ ) {

int x = k + dx8[i]; int y = j + dy8[i];

vector istaken(sz, false);

const int dx8[8] = {-1, -1, 0, 1, 1, 1, 0, -1}; const int dy8[8] = { 0, -1, -1, -1, 0, 1, 1, 1}; unsigned int*& int*&

const int& const int&

ubuff, labels, width, height,

color )

const unsigned int&

}*/

}

mainindex++;

int sz = width*height;

vector istaken(sz, false);

vector contourx(sz);vector contoury(sz); int mainindex(0);int cind(0); for( int j = 0; j < height; j++ ) { }

for( int k = 0; k < width; k++ ) { }

int np(0);

for( int i = 0; i < 8; i++ ) { }

if( np > 1 ) { }

mainindex++;

contourx[cind] = k; contoury[cind] = j; istaken[mainindex] = true; //img[mainindex] = color; cind++;

int x = k + dx8[i]; int y = j + dy8[i];

if( (x >= 0 && x < width) && (y >= 0 && y < height) ) { }

int index = y*width + x;

//if( false == istaken[index] )//comment this to obtain internal contours { }

if( labels[mainindex] != labels[index] ) np++;

}

int numboundpix = cind;//int(contourx.size()); for( int j = 0; j < numboundpix; j++ ) { }

int ii = contoury[j]*width + contourx[j]; ubuff[ii] = 0xffffff; for( int n = 0; n < 8; n++ ) { }

int x = contourx[j] + dx8[n]; int y = contoury[j] + dy8[n];

if( (x >= 0 && x < width) && (y >= 0 && y < height) ) { }

int ind = y*width + x;

if(!istaken[ind]) ubuff[ind] = 0;

//============================================================================== /// DetectLabEdges

//============================================================================== void SLIC::DetectLabEdges( {

double dx = (lvec[i-1]-lvec[i+1])*(lvec[i-1]-lvec[i+1]) +

edges.resize(sz,0);

for( int j = 1; j < height-1; j++ ) {

for( int k = 1; k < width-1; k++ ) {

int i = j*width+k;

int sz = width*height; const double* const double* const double* const int& const int&

lvec, avec, bvec,

width, height, edges)

vector&

}

}

}

(avec[i-1]-avec[i+1])*(avec[i-1]-avec[i+1]) + (bvec[i-1]-bvec[i+1])*(bvec[i-1]-bvec[i+1]);

double dy = (lvec[i-width]-lvec[i+width])*(lvec[i-width]-lvec[i+width]) +

(avec[i-width]-avec[i+width])*(avec[i-width]-avec[i+width]) + (bvec[i-width]-bvec[i+width])*(bvec[i-width]-bvec[i+width]);

//edges[i] = fabs(dx) + fabs(dy); edges[i] = dx*dx + dy*dy;

//=========================================================================== /// PerturbSeeds

//=========================================================================== void SLIC::PerturbSeeds( {

int storeind = oind;

for( int i = 0; i < 8; i++ ) {

int nx = ox+dx8[i];//new x int ny = oy+dy8[i];//new y

for( int n = 0; n < numseeds; n++ ) {

int ox = kseedsx[n];//original x int oy = kseedsy[n];//original y int oind = oy*m_width + ox;

const int dx8[8] = {-1, -1, 0, 1, 1, 1, 0, -1}; const int dy8[8] = { 0, -1, -1, -1, 0, 1, 1, 1};

int numseeds = kseedsl.size(); vector& vector& vector& vector& vector&

kseedsl, kseedsa, kseedsb, kseedsx, kseedsy,

const vector& edges)

}

}

}

if( nx >= 0 && nx < m_width && ny >= 0 && ny < m_height) { }

int nind = ny*m_width + nx; if( edges[nind] < edges[storeind]) { }

storeind = nind;

if(storeind != oind) { }

kseedsx[n] = storeind%m_width; kseedsy[n] = storeind/m_width; kseedsl[n] = m_lvec[storeind]; kseedsa[n] = m_avec[storeind]; kseedsb[n] = m_bvec[storeind];

//=========================================================================== /// GetLABXYSeeds_ForGivenStepSize ///

/// The k seed values are taken as uniform spatial pixel samples.

//=========================================================================== void SLIC::GetLABXYSeeds_ForGivenStepSize(

vector& vector& vector& vector& vector&

kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, STEP,

perturbseeds,

const int&

const bool& {

const vector& edgemag) const bool hexgrid = false;

//int xstrips = m_width/STEP; int numseeds(0); int n(0);

//int ystrips = m_height/STEP;

int xstrips = (0.5+double(m_width)/double(STEP)); int ystrips = (0.5+double(m_height)/double(STEP));

int xerr = m_width - STEP*xstrips;if(xerr < 0){xstrips--;xerr = m_width - STEP*xstrips;} int yerr = m_height - STEP*ystrips;if(yerr < 0){ystrips--;yerr = m_height- STEP*ystrips;}

for( int y = 0; y < ystrips; y++ ) {

int ye = y*yerrperstrip;

for( int x = 0; x < xstrips; x++ ) {

int xe = x*xerrperstrip;

int xoff = STEP/2; int yoff = STEP/2;

//------------------------- numseeds = xstrips*ystrips; //------------------------- kseedsl.resize(numseeds); kseedsa.resize(numseeds); kseedsb.resize(numseeds); kseedsx.resize(numseeds); kseedsy.resize(numseeds);

double xerrperstrip = double(xerr)/double(xstrips); double yerrperstrip = double(yerr)/double(ystrips);

int seedx = (x*STEP+xoff+xe);

if(hexgrid){ seedx = x*STEP+(xoff<<(y&0x1))+xe; seedx = min(m_width-1,seedx); }//for hex grid sampling int seedy = (y*STEP+yoff+ye); int i = seedy*m_width + seedx;

kseedsl[n] = m_lvec[i]; kseedsa[n] = m_avec[i]; kseedsb[n] = m_bvec[i];

kseedsx[n] = seedx; kseedsy[n] = seedy;

}

}

n++;

}

//=========================================================================== /// GetKValues_LABXYZ ///

/// The k seed values are taken as uniform spatial pixel samples.

//=========================================================================== void SLIC::GetKValues_LABXYZ( {

const bool hexgrid = false;

int xerr = m_width - STEP*xstrips;if(xerr < 0){xstrips--;xerr = m_width - STEP*xstrips;} int yerr = m_height - STEP*ystrips;if(yerr < 0){ystrips--;yerr = m_height- STEP*ystrips;} int zerr = m_depth - STEP*zstrips;if(zerr < 0){zstrips--;zerr = m_depth - STEP*zstrips;}

int xoff = STEP/2; int yoff = STEP/2; int zoff = STEP/2;

double xerrperstrip = double(xerr)/double(xstrips); double yerrperstrip = double(yerr)/double(ystrips); double zerrperstrip = double(zerr)/double(zstrips); int xstrips = (0.5+double(m_width)/double(STEP)); int ystrips = (0.5+double(m_height)/double(STEP)); int zstrips = (0.5+double(m_depth)/double(STEP)); int numseeds(0); int n(0);

vector& vector& vector& vector& vector& vector&

kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, kseedsz, STEP)

if(perturbseeds) { }

PerturbSeeds(kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, edgemag);

const int&

}

//-------------------------

numseeds = xstrips*ystrips*zstrips; //------------------------- kseedsl.resize(numseeds); kseedsa.resize(numseeds); kseedsb.resize(numseeds); kseedsx.resize(numseeds); kseedsy.resize(numseeds); kseedsz.resize(numseeds);

for( int z = 0; z < zstrips; z++ ) { }

int ze = z*zerrperstrip; int d = (z*STEP+zoff+ze);

for( int y = 0; y < ystrips; y++ ) { }

int ye = y*yerrperstrip;

for( int x = 0; x < xstrips; x++ ) { }

int xe = x*xerrperstrip;

int i = (y*STEP+yoff+ye)*m_width + (x*STEP+xoff+xe);

kseedsl[n] = m_lvecvec[d][i]; kseedsa[n] = m_avecvec[d][i]; kseedsb[n] = m_bvecvec[d][i]; kseedsx[n] = (x*STEP+xoff+xe); kseedsy[n] = (y*STEP+yoff+ye); kseedsz[n] = d; n++;

//=========================================================================== /// PerformSuperpixelSLIC ///

/// Performs k mean segmentation. It is fast because it looks locally, not /// over the entire image.

//=========================================================================== void SLIC::PerformSuperpixelSLIC(

vector& vector& vector& vector& vector&

M)

kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, STEP,

int*& klabels,

const int& {

const double&

const vector& edgemag,

int sz = m_width*m_height; const int numk = kseedsl.size(); //---------------- int offset = STEP; //----------------

vector clustersize(numk, 0);

vector inv(numk, 0);//to store 1/clustersize[k] values vector sigmal(numk, 0); vector sigmaa(numk, 0); vector sigmab(numk, 0); vector sigmax(numk, 0); vector sigmay(numk, 0); vector distvec(sz, DBL_MAX); double invwt = 1.0/((STEP/M)*(STEP/M)); int x1, y1, x2, y2; double l, a, b; double dist; double distxy;

for( int itr = 0; itr < 10; itr++ ) {

distvec.assign(sz, DBL_MAX); for( int n = 0; n < numk; n++ ) {

kseedsy[n]-offset);

kseedsy[n]+offset); kseedsx[n]-offset);

//if(STEP < 8) offset = STEP*1.5;//to prevent a crash due to a very small step size

y1 = max(0.0, x1 = max(0.0,

y2 = min((double)m_height,

x2 = min((double)m_width,

sigmal.assign(numk, 0); sigmaa.assign(numk, 0); }

}

}

if( dist < distvec[i] ) { }

distvec[i] = dist; klabels[i] = n;

distxy =

dist =

l = m_lvec[i]; a = m_avec[i]; b = m_bvec[i];

for( int y = y1; y < y2; y++ ) {

for( int x = x1; x < x2; x++ ) {

int i = y*m_width + x;

kseedsx[n]+offset);

(l - kseedsl[n])*(l - kseedsl[n]) + (a - kseedsa[n])*(a - kseedsa[n]) + (b - kseedsb[n])*(b - kseedsb[n]);

(x - kseedsx[n])*(x - kseedsx[n]) +

(y - kseedsy[n])*(y - kseedsy[n]);

//------------------------------------------------------------------------

dist += distxy*invwt;//dist = sqrt(dist) + sqrt(distxy*invwt);//this is

more exact

//------------------------------------------------------------------------

//----------------------------------------------------------------- // Recalculate the centroid and store in the seed values

//----------------------------------------------------------------- //instead of reassigning memory on each iteration, just reset.

sigmab.assign(numk, 0); sigmax.assign(numk, 0); sigmay.assign(numk, 0); clustersize.assign(numk, 0);

//------------------------------------ //edgesum.assign(numk, 0);

//------------------------------------ {int ind(0);

for( int r = 0; r < m_height; r++ ) { }}

{for( int k = 0; k < numk; k++ ) { }}

{for( int k = 0; k < numk; k++ ) {

kseedsl[k] = sigmal[k]*inv[k]; kseedsa[k] = sigmaa[k]*inv[k]; kseedsb[k] = sigmab[k]*inv[k]; kseedsx[k] = sigmax[k]*inv[k]; kseedsy[k] = sigmay[k]*inv[k];

//------------------------------------ //edgesum[k] *= inv[k];

if( clustersize[k] <= 0 ) clustersize[k] = 1;

inv[k] = 1.0/clustersize[k];//computing inverse now to multiply, than divide later for( int c = 0; c < m_width; c++ ) { }

sigmal[klabels[ind]] += m_lvec[ind]; sigmaa[klabels[ind]] += m_avec[ind]; sigmab[klabels[ind]] += m_bvec[ind]; sigmax[klabels[ind]] += c; sigmay[klabels[ind]] += r;

//------------------------------------ //edgesum[klabels[ind]] += edgemag[ind]; //------------------------------------ clustersize[klabels[ind]] += 1.0; ind++;

}

}

}}

//------------------------------------

//=========================================================================== /// PerformSupervoxelSLIC ///

/// Performs k mean segmentation. It is fast because it searches locally, not /// over the entire image.

//=========================================================================== void SLIC::PerformSupervoxelSLIC(

vector& vector& vector& vector& vector& vector&

kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, kseedsz, klabels, STEP,

int**& {

const int&

const double&

compactness)

int sz = m_width*m_height; const int numk = kseedsl.size();

//int numitr(0);

//---------------- int offset = STEP; //----------------

vector clustersize(numk, 0);

vector inv(numk, 0);//to store 1/clustersize[k] values vector sigmal(numk, 0); vector sigmaa(numk, 0); vector sigmab(numk, 0); vector sigmax(numk, 0); vector sigmay(numk, 0); vector sigmaz(numk, 0);

//if(STEP < 8) offset = STEP*1.5;//to prevent a crash due to a very small step size

vector< double > initdouble(sz, DBL_MAX);

vector< vector > distvec(m_depth, initdouble); //vector distvec(sz, DBL_MAX);

double invwt = 1.0/((STEP/compactness)*(STEP/compactness));//compactness = 20.0 is usually

good.

int x1, y1, x2, y2, z1, z2; double l, a, b; double dist; double distxyz;

for( int itr = 0; itr < 5; itr++ ) {

distvec.assign(m_depth, initdouble); for( int n = 0; n < numk; n++ ) {

kseedsy[n]-offset);

kseedsy[n]+offset); kseedsx[n]+offset); kseedsz[n]+offset); kseedsx[n]-offset); kseedsz[n]-offset);

y1 = max(0.0, x1 = max(0.0, z1 = max(0.0,

distxyz =

dist =

y2 = min((double)m_height, x2 = min((double)m_width, z2 = min((double)m_depth,

for( int z = z1; z < z2; z++ ) {

for( int y = y1; y < y2; y++ ) {

for( int x = x1; x < x2; x++ ) {

int i = y*m_width + x; l = m_lvecvec[z][i]; a = m_avecvec[z][i]; b = m_bvecvec[z][i];

(l - kseedsl[n])*(l - kseedsl[n]) + (a - kseedsa[n])*(a - kseedsa[n]) + (b - kseedsb[n])*(b - kseedsb[n]); (x - kseedsx[n])*(x - kseedsx[n]) +

}

}

}

(y - kseedsy[n])*(y - kseedsy[n]) + (z - kseedsz[n])*(z - kseedsz[n]);

//------------------------------------------------------------------------

dist += distxyz*invwt;

//------------------------------------------------------------------------

}

if( dist < distvec[z][i] ) { }

distvec[z][i] = dist; klabels[z][i] = n;

//----------------------------------------------------------------- // Recalculate the centroid and store in the seed values

//----------------------------------------------------------------- //instead of reassigning memory on each iteration, just reset. sigmal.assign(numk, 0); sigmaa.assign(numk, 0); sigmab.assign(numk, 0); sigmax.assign(numk, 0); sigmay.assign(numk, 0); sigmaz.assign(numk, 0); clustersize.assign(numk, 0); for( int d = 0; d < m_depth; d++ ) {

int ind(0);

for( int r = 0; r < m_height; r++ ) {

for( int c = 0; c < m_width; c++ ) {

sigmal[klabels[d][ind]] += m_lvecvec[d][ind]; sigmaa[klabels[d][ind]] += m_avecvec[d][ind]; sigmab[klabels[d][ind]] += m_bvecvec[d][ind]; sigmax[klabels[d][ind]] += c; sigmay[klabels[d][ind]] += r;

}

}

}

}

}

sigmaz[klabels[d][ind]] += d; clustersize[klabels[d][ind]] += 1.0; ind++;

{for( int k = 0; k < numk; k++ ) { }}

{for( int k = 0; k < numk; k++ ) { }}

kseedsl[k] = sigmal[k]*inv[k]; kseedsa[k] = sigmaa[k]*inv[k]; kseedsb[k] = sigmab[k]*inv[k]; kseedsx[k] = sigmax[k]*inv[k]; kseedsy[k] = sigmay[k]*inv[k]; kseedsz[k] = sigmaz[k]*inv[k];

if( clustersize[k] <= 0 ) clustersize[k] = 1;

inv[k] = 1.0/clustersize[k];//computing inverse now to multiply, than divide later

//=========================================================================== /// SaveSuperpixelLabels ///

/// Save labels in raster scan order.

//=========================================================================== void SLIC::SaveSuperpixelLabels( {

#ifdef WINDOWS

char fname[256];

const int*& const int& const int&

labels, width, height,

const string& const string&

filename, path)

char extn[256];

_splitpath(filename.c_str(), NULL, NULL, fname, extn); string temp = fname;

string finalpath = path + temp + string(\); #else

string nameandextension = filename; size_t pos = filename.find_last_of(\);

if(pos != string::npos)//if a slash is found, then take the filename with extension {

nameandextension = filename.substr(pos+1); }

string newname = nameandextension.replace(nameandextension.rfind(\)+1, 3, \);//find the position of the dot and replace the 3 characters following it. string finalpath = path+newname; #endif

int sz = width*height; }

//=========================================================================== /// SaveSupervoxelLabels ///

/// Save labels in raster scan order.

//=========================================================================== void SLIC::SaveSupervoxelLabels( {

#ifdef WINDOWS

const int**& const int& const int& const int&

labels,

width, height, depth,

ofstream outfile;

outfile.open(finalpath.c_str(), ios::binary); for( int i = 0; i < sz; i++ ) { }

outfile.close();

outfile.write((const char*)&labels[i], sizeof(int));

const string& const string&

filename, path)

char fname[256]; char extn[256];

_splitpath(filename.c_str(), NULL, NULL, fname, extn); string temp = fname;

string finalpath = path + temp + string(\); #else

string nameandextension = filename; size_t pos = filename.find_last_of(\);

if(pos != string::npos)//if a slash is found, then take the filename with extension {

nameandextension = filename.substr(pos+1); }

string newname = nameandextension.replace(nameandextension.rfind(\)+1, 3, \);//find the position of the dot and replace the 3 characters following it. string finalpath = path+newname; #endif

int sz = width*height; }

//=========================================================================== /// EnforceLabelConnectivity /// /// /// ///

1. finding an adjacent label for each new component at the start 2. if a certain component is too small, assigning the previously found adjacent label to this component, and not incrementing the label. ofstream outfile;

outfile.open(finalpath.c_str(), ios::binary); for( int d = 0; d < depth; d++ ) { }

outfile.close();

for( int i = 0; i < sz; i++ ) { }

outfile.write((const char*)&labels[d][i], sizeof(int));

//=========================================================================== void SLIC::EnforceLabelConnectivity(

const int* const int

labels,//input labels that need to be corrected to remove width,

stray labels

{

const int int*& int&

height,

nlabels,//new labels

numlabels,//the number of labels changes in the end if segments

K) //the number of superpixels desired by the user

are removed

const int&

// const int dx8[8] = {-1, -1, 0, 1, 1, 1, 0, -1}; // const int dy8[8] = { 0, -1, -1, -1, 0, 1, 1, 1};

const int sz = width*height; const int SUPSZ = sz/K; //nlabels.resize(sz, -1);

for( int i = 0; i < sz; i++ ) nlabels[i] = -1; int label(0);

int* xvec = new int[sz]; int* yvec = new int[sz]; int oindex(0);

int adjlabel(0);//adjacent label for( int j = 0; j < height; j++ ) {

for( int k = 0; k < width; k++ ) {

if( 0 > nlabels[oindex] ) {

nlabels[oindex] = label; //-------------------- // Start a new segment //-------------------- xvec[0] = k; yvec[0] = j;

//------------------------------------------------------- // Quickly find an adjacent label for use later if needed //------------------------------------------------------- {for( int n = 0; n < 4; n++ ) {

int x = xvec[0] + dx4[n]; int y = yvec[0] + dy4[n];

if( (x >= 0 && x < width) && (y >= 0 && y < height) )

const int dx4[4] = {-1, 0, 1, 0}; const int dy4[4] = { 0, -1, 0, 1};

}}

{ }

int nindex = y*width + x;

if(nlabels[nindex] >= 0) adjlabel = nlabels[nindex];

int count(1);

for( int c = 0; c < count; c++ ) { }

//------------------------------------------------------- // If segment size is less then a limit, assign an

// adjacent label found before, and decrement label count. //------------------------------------------------------- if(count <= SUPSZ >> 2) {

for( int c = 0; c < count; c++ ) { } label--;

int ind = yvec[c]*width+xvec[c]; nlabels[ind] = adjlabel; for( int n = 0; n < 4; n++ ) { }

int x = xvec[c] + dx4[n]; int y = yvec[c] + dy4[n];

if( (x >= 0 && x < width) && (y >= 0 && y < height) ) { }

int nindex = y*width + x;

if( 0 > nlabels[nindex] && labels[oindex] == labels[nindex] ) { }

xvec[count] = x; yvec[count] = y;

nlabels[nindex] = label; count++;

}

}

}

}

} label++;

oindex++;

numlabels = label; if(xvec) delete [] xvec; if(yvec) delete [] yvec;

//=========================================================================== /// RelabelStraySupervoxels

//=========================================================================== void SLIC::EnforceSupervoxelLabelConnectivity( {

int adjlabel(0);//adjacent label

int* xvec = new int[SUPSZ*10];//a large enough size int* yvec = new int[SUPSZ*10];//a large enough size int* zvec = new int[SUPSZ*10];//a large enough size

//------------------ // memory allocation //------------------

int** nlabels = new int*[depth]; {for( int d = 0; d < depth; d++ ) {

int sz = width*height;

const int SUPSZ = STEP*STEP*STEP;

const int dx10[10] = {-1, 0, 1, 0, -1, 1, 1, -1, 0, 0}; const int dy10[10] = { 0, -1, 0, 1, -1, -1, 1, 1, 0, 0}; const int dz10[10] = { 0, 0, 0, 0, 0, 0, 0, 0, -1, 1}; int**& const int& const int& const int& int&

const int&

labels,//input - previous labels, output - new labels width, height, depth, STEP)

numlabels,

}}

nlabels[d] = new int[sz];

for( int i = 0; i < sz; i++ ) nlabels[d][i] = -1;

//------------------ // labeling

//------------------ int lab(0);

{for( int d = 0; d < depth; d++ ) {

int i(0);

for( int h = 0; h < height; h++ ) {

for( int w = 0; w < width; w++ ) {

if(nlabels[d][i] < 0) {

nlabels[d][i] = lab;

//------------------------------------------------------- // Quickly find an adjacent label for use later if needed //------------------------------------------------------- {for( int n = 0; n < 10; n++ ) { }}

xvec[0] = w; yvec[0] = h; zvec[0] = d; int count(1);

for( int c = 0; c < count; c++ ) {

for( int n = 0; n < 10; n++ ) int x = w + dx10[n]; int y = h + dy10[n]; int z = d + dz10[n];

if( (x >= 0 && x < width) && (y >= 0 && y < height) && (z >= 0 && { }

int nindex = y*width + x; if(nlabels[z][nindex] >= 0) { }

adjlabel = nlabels[z][nindex];

z < depth) )

}

}

{ }

int x = xvec[c] + dx10[n]; int y = yvec[c] + dy10[n]; int z = zvec[c] + dz10[n];

if( (x >= 0 && x < width) && (y >= 0 && y < height) && (z >= 0 { }

int nindex = y*width + x;

if( 0 > nlabels[z][nindex] && labels[d][i] == { }

xvec[count] = x; yvec[count] = y; zvec[count] = z;

nlabels[z][nindex] = lab; count++;

&& z < depth))

labels[z][nindex] )

//------------------------------------------------------- // If segment size is less then a limit, assign an

// adjacent label found before, and decrement label count. //-------------------------------------------------------

if(count <= (SUPSZ >> 2))//this threshold can be changed according to { }

//-------------------------------------------------------- lab++;

for( int c = 0; c < count; c++ ) { } lab--;

int ind = yvec[c]*width+xvec[c]; nlabels[zvec[c]][ind] = adjlabel;

needs

i++;

}

}}

}

}

//------------------ // mem de-allocation //------------------

{for( int d = 0; d < depth; d++ ) { }}

{for( int d = 0; d < depth; d++ ) { }}

delete [] nlabels; //------------------ if(xvec) delete [] xvec; if(yvec) delete [] yvec; if(zvec) delete [] zvec; //------------------ numlabels = lab; //------------------

delete [] nlabels[d];

for( int i = 0; i < sz; i++ ) labels[d][i] = nlabels[d][i];

//=========================================================================== /// DoSuperpixelSegmentation_ForGivenSuperpixelSize ///

/// The input parameter ubuff conains RGB values in a 32-bit unsigned integers /// as follows: ///

/// [1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1] ///

/// Nothing R G B ///

/// The RGB values are accessed from (and packed into) the unsigned integers /// using bitwise operators as can be seen in the function DoRGBtoLABConversion(). ///

/// compactness value depends on the input pixels values. For instance, if /// the input is greyscale with values ranging from 0-100, then a compactness /// value of 20.0 would give good results. A greater value will make the /// superpixels more compact while a smaller value would make them more uneven.

///

/// The labels can be saved if needed using SaveSuperpixelLabels()

//=========================================================================== void SLIC::DoSuperpixelSegmentation_ForGivenSuperpixelSize( const unsigned int* ubuff,

const int const int int*& int&

width, height, klabels, superpixelsize,

numlabels,

const int& {

const double& compactness)

//------------------------------------------------ const int STEP = sqrt(double(superpixelsize))+0.5; //------------------------------------------------

//-------------------------------------------------- m_width = width; m_height = height;

int sz = m_width*m_height; //klabels.resize( sz, -1 );

//-------------------------------------------------- klabels = new int[sz];

for( int s = 0; s < sz; s++ ) klabels[s] = -1; vector kseedsl(0); vector kseedsa(0); vector kseedsb(0); vector kseedsx(0); vector kseedsy(0);

//-------------------------------------------------- if(1)//LAB, the default option {

DoRGBtoLABConversion(ubuff, m_lvec, m_avec, m_bvec); }

else//RGB {

m_lvec = new double[sz]; m_avec = new double[sz]; m_bvec = new double[sz]; for( int i = 0; i < sz; i++ ) {

m_lvec[i] = ubuff[i] >> 16 & 0xff; m_avec[i] = ubuff[i] >> 8 & 0xff;

m_bvec[i] = ubuff[i] & 0xff; } }

//--------------------------------------------------

bool perturbseeds(false);//perturb seeds is not absolutely necessary, one can set this flag to false }

//=========================================================================== /// DoSuperpixelSegmentation_ForGivenNumberOfSuperpixels ///

/// The input parameter ubuff conains RGB values in a 32-bit unsigned integers /// as follows: ///

/// [1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1] ///

/// Nothing R G B ///

/// The RGB values are accessed from (and packed into) the unsigned integers /// using bitwise operators as can be seen in the function DoRGBtoLABConversion(). ///

/// compactness value depends on the input pixels values. For instance, if /// the input is greyscale with values ranging from 0-100, then a compactness /// value of 20.0 would give good results. A greater value will make the /// superpixels more compact while a smaller value would make them more uneven. ///

/// The labels can be saved if needed using SaveSuperpixelLabels()

int* nlabels = new int[sz];

EnforceLabelConnectivity(klabels, m_width, m_height, nlabels, numlabels, {for(int i = 0; i < sz; i++ ) klabels[i] = nlabels[i];} if(nlabels) delete [] nlabels;

PerformSuperpixelSLIC(kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, klabels, STEP, numlabels = kseedsl.size(); edgemag,compactness);

vector edgemag(0);

if(perturbseeds) DetectLabEdges(m_lvec, m_avec, m_bvec, m_width, m_height, edgemag); GetLABXYSeeds_ForGivenStepSize(kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, STEP,

perturbseeds, edgemag);

double(sz)/double(STEP*STEP));

//=========================================================================== void SLIC::DoSuperpixelSegmentation_ForGivenNumberOfSuperpixels( const unsigned int* ubuff,

const int const int int*& int&

width, height, klabels,

K,//required number of superpixels

numlabels,

const int&

const double& compactness)//weight given to spatial distance {

const int superpixelsize = 0.5+double(width*height)/double(K);

DoSuperpixelSegmentation_ForGivenSuperpixelSize(ubuff,width,height,klabels,numlabels,superpixelsize,compactness); }

//=========================================================================== /// DoSupervoxelSegmentation ///

/// There is option to save the labels if needed. ///

/// The input parameter ubuffvec holds all the video frames. It is a

/// 2-dimensional array. The first dimension is depth and the second dimension /// is pixel location in a frame. For example, to access a pixel in the 3rd /// frame (i.e. depth index 2), in the 4th row (i.e. height index 3) on the /// 37th column (i.e. width index 36), you would write: ///

/// unsigned int the_pixel_i_want = ubuffvec[2][3*width + 36] ///

/// In addition, here is how the RGB values are contained in a 32-bit unsigned /// integer: ///

/// [1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1] ///

/// Nothing R G B ///

/// The RGB values are accessed from (and packed into) the unsigned integers /// using bitwise operators as can be seen in the function DoRGBtoLABConversion(). ///

/// compactness value depends on the input pixels values. For instance, if

/// the input is greyscale with values ranging from 0-100, then a compactness /// value of 20.0 would give good results. A greater value will make the /// supervoxels more compact while a smaller value would make them more uneven. //=========================================================================== void SLIC::DoSupervoxelSegmentation(

unsigned int**& const int& const int& const int& int**& int&

ubuffvec, width, height, depth, klabels, supervoxelsize,

numlabels,

const int& {

const double& compactness)

//--------------------------------------------------------- const int STEP = 0.5 + pow(double(supervoxelsize),1.0/3.0); //---------------------------------------------------------

//-------------------------------------------------- m_width = width; m_height = height; m_depth = depth;

int sz = m_width*m_height;

//-------------------------------------------------- m_lvecvec = new double*[depth]; m_avecvec = new double*[depth]; m_bvecvec = new double*[depth]; for( int d = 0; d < depth; d++ ) {

m_lvecvec[d] = new double[sz]; m_avecvec[d] = new double[sz]; m_bvecvec[d] = new double[sz]; vector kseedsl(0); vector kseedsa(0); vector kseedsb(0); vector kseedsx(0); vector kseedsy(0); vector kseedsz(0);

//klabels = new int*[depth];

//klabels[d] = new int[sz];

}

}

for( int s = 0; s < sz; s++ ) { }

klabels[d][s] = -1;

DoRGBtoLABConversion(ubuffvec, m_lvecvec, m_avecvec, m_bvecvec);

GetKValues_LABXYZ(kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, kseedsz, STEP);

PerformSupervoxelSLIC(kseedsl, kseedsa, kseedsb, kseedsx, kseedsy, kseedsz, klabels, STEP,

compactness);

EnforceSupervoxelLabelConnectivity(klabels, width, height, depth, numlabels, STEP);

SLICSuperpixels.cpp

// SLICSuperpixels.cpp : Defines the class behaviors for the application. //

#include \

#include \ #include \

#ifdef _DEBUG

#define new DEBUG_NEW #endif

// CSLICSuperpixelsApp

BEGIN_MESSAGE_MAP(CSLICSuperpixelsApp, CWinAppEx)

// CSLICSuperpixelsApp construction

ON_COMMAND(ID_HELP, &CWinApp::OnHelp) END_MESSAGE_MAP()

CSLICSuperpixelsApp::CSLICSuperpixelsApp() { }

// The one and only CSLICSuperpixelsApp object

CSLICSuperpixelsApp theApp;

// CSLICSuperpixelsApp initialization

BOOL CSLICSuperpixelsApp::InitInstance() {

CSLICSuperpixelsDlg dlg; m_pMainWnd = &dlg;

INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) { }

else if (nResponse == IDCANCEL) { }

// TODO: Place code here to handle when the dialog is // dismissed with Cancel

// TODO: Place code here to handle when the dialog is // dismissed with OK // Standard initialization

// If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need // Change the registry key under which our settings are stored // TODO: You should modify this string to be something appropriate // such as the name of your company or organization

SetRegistryKey(_T(\)); CWinAppEx::InitInstance();

// TODO: add construction code here,

// Place all significant initialization in InitInstance

}

// Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE;

SLICSuperpixelsDlg.cpp

// SLICSuperpixelsDlg.cpp : implementation file //

#include \

#include \ #include \ #include \ #include \

#ifdef _DEBUG

#define new DEBUG_NEW #endif

// CSLICSuperpixelsDlg dialog

CSLICSuperpixelsDlg::CSLICSuperpixelsDlg(CWnd* pParent /*=NULL*/) { }

void CSLICSuperpixelsDlg::DoDataExchange(CDataExchange* pDX) {

CDialog::DoDataExchange(pDX);

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); : CDialog(CSLICSuperpixelsDlg::IDD, pParent) , m_spcount(0) , m_compactness(0)

}

DDX_Text(pDX, IDC_EDIT_SPCOUNT, m_spcount); DDV_MinMaxInt(pDX, m_spcount, 1, 10000000);

DDX_Text(pDX, IDC_EDIT_COMPACTNESS, m_compactness); DDV_MinMaxDouble(pDX, m_compactness, 1.0, 80.0);

BEGIN_MESSAGE_MAP(CSLICSuperpixelsDlg, CDialog)

// CSLICSuperpixelsDlg message handlers

BOOL CSLICSuperpixelsDlg::OnInitDialog() { }

void CSLICSuperpixelsDlg::OnEnChangeEditSpcount() {

// TODO: If this is a RICHEDIT control, the control will not

// send this notification unless you override the CDialog::OnInitDialog() // function and call CRichEditCtrl().SetEventMask()

return TRUE; // return TRUE unless you set the focus to a control // TODO: Add extra initialization here m_spcount = 200; m_compactness = 10.0;

UpdateData(FALSE);//FALSE to set data, TRUE to retrieve data

// Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE);

// Set big icon

SetIcon(m_hIcon, FALSE);

// Set small icon

CDialog::OnInitDialog(); ON_WM_PAINT()

ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP

ON_BN_CLICKED(IDC_BUTTON_CREATESUPERPIXELS,

ON_EN_CHANGE(IDC_EDIT_SPCOUNT, &CSLICSuperpixelsDlg::OnEnChangeEditSpcount)

ON_EN_CHANGE(IDC_EDIT_COMPACTNESS, &CSLICSuperpixelsDlg::OnEnChangeEditCompactness)

&CSLICSuperpixelsDlg::OnBnClickedButtonCreatesuperpixels)

END_MESSAGE_MAP()

本文来源:https://www.bwwdw.com/article/7szd.html

Top