#include "RSMeanShift.h" #ifdef NICE_USELIB_OPENMP #include #endif #include #include #include "core/basics/StringTools.h" using namespace std; using namespace NICE; using namespace OBJREC; RSMeanShift::RSMeanShift() { minimumRegionArea = 50; rangeBandwidth = 6.5; spatialBandwidth = 7; imageProc = new msImageProcessor(); speedUpLevel = MED_SPEEDUP; } RSMeanShift::RSMeanShift ( const Config *conf ) { imageProc = new msImageProcessor(); minimumRegionArea = conf->gI ( "RSMeanShift", "MinimumRegionArea", 50 ); rangeBandwidth = conf->gD ( "RSMeanShift", "RangeBandwidth", 6.5 ); spatialBandwidth = conf->gI ( "RSMeanShift", "SpatialBandwidth", 7 ); speedUpLvlStr = conf->gS ( "RSMeanShift", "SpeedUpLevel", "MEDIUM" ); if ( speedUpLvlStr == "NONE" ) speedUpLevel = NO_SPEEDUP; else if ( speedUpLvlStr == "MEDIUM" ) speedUpLevel = MED_SPEEDUP; else if ( speedUpLvlStr == "HIGH" ) speedUpLevel = HIGH_SPEEDUP; else { cerr << "[err] RSMeanShift::RSMeanShift: Wrong SpeedUpLevel-Value (" << speedUpLvlStr << ") only NONE, MEDIUM and HIGH allowed! Take default Value (MED_SPEEDUP)" << endl; speedUpLevel = MED_SPEEDUP; } } RSMeanShift::~RSMeanShift() { delete imageProc; } int RSMeanShift::segRegions ( const NICE::Image & img, NICE::Matrix & mask ) const { ColorImage cimg ( img.width(), img.height() ); for(int y = 0; y < img.height(); y++) { for(int x = 0; x < img.width(); x++) { for(int c = 0; c < 3; c++) { cimg.setPixelQuick(x,y,c,img.getPixelQuick(x,y)); } } } return segRegions ( cimg, mask ); } int RSMeanShift::segRegions ( const NICE::ColorImage & img, NICE::Matrix & mask ) const { clog << "[log] RSMeanShift::segRegions: EDISON-Implementation" << endl; /* >> ColorImage an EDISON uebergeben BEM: Dabei werden die Bilddaten als Pointer an die msImageProcessor::DefineImage Methode uebergeben. Der Parameter hat in der EDISON-Implementierung KEINEN 'const' Qualifier. */ unsigned int width = img.width(); unsigned int height = img.height(); const unsigned int channels = 3; // notwendiger Bildspeicher const unsigned int imageSize = width * height * channels; byte* rawImageData = NULL; #ifdef NICE_USELIB_IPP /* ipp Speichert die Bilddaten anders, so dass das Bild pixelweise kopiert werden muss. */ // Speicher fuer das Bild reservieren rawImageData = new byte[ imageSize ]; // Pixelkoordinaten unsigned int x, y; x = y = 0; // "Breite" des Bildes im Speicher // unsigned int yStepWidth = width * 3; for ( unsigned int i = 0; i < imageSize; i += 3 ) { rawImageData[ i ] = img.getPixel ( x, y, 0 ); rawImageData[ i + 1 ] = img.getPixel ( x, y, 1 ); rawImageData[ i + 2 ] = img.getPixel ( x, y, 2 ); // neue Pixelkoordinaten berechnen if ( ( ++x ) == width ) { x = 0; y++; } } #else // img in nicht 'const' ColorImage kopieren ColorImage tempImage ( img ); rawImageData = tempImage.getPixelPointer(); #endif imageProc->DefineImage ( rawImageData, COLOR, height, width ); /* >> Segementierung durchfuehren */ imageProc->Segment ( spatialBandwidth, rangeBandwidth, minimumRegionArea, speedUpLevel ); /* >> Ergebnisbild aus EDISON auslesen */ byte resultRawImageData[ width * height * 3 ]; imageProc->GetResults ( resultRawImageData ); /* >> Maske erstellen */ #ifdef NICE_USELIB_IPP delete[] rawImageData; rawImageData = 0; ColorImage ippTempImage ( width, height ); x = y = 0; for ( unsigned int i = 0; i < imageSize; i += 3 ) { ippTempImage.setPixel ( x, y, 0, resultRawImageData[ i ] ); ippTempImage.setPixel ( x, y, 1, resultRawImageData[ i + 1 ] ); ippTempImage.setPixel ( x, y, 2, resultRawImageData[ i + 2 ] ); // neue Pixelkoordinaten berechnen if ( ( ++x ) == width ) { x = 0; y++; } } return transformSegmentedImg ( ippTempImage, mask ); #else return transformSegmentedImg ( ColorImage ( resultRawImageData, width, height, GrayColorImageCommonImplementation::noAlignment ), mask ); #endif }