示例#1
0
bool IPLCompassMask::processInputData(IPLImage* image , int, bool)
{
    // delete previous result
    delete _result;
    _result = NULL;

    int width = image->width();
    int height = image->height();
    _result = new IPLImage( image->type(), width, height );

    // get properties
    int maskType = getProcessPropertyInt("maskType");
    int direction = getProcessPropertyInt("direction");

    int progress = 0;
    int maxProgress = image->height() * image->getNumberOfPlanes();
    int nrOfPlanes = image->getNumberOfPlanes();

    int startDir = ( direction == 8 )? 0 : direction;
    int endDir = ( direction == 8 )? 7 : direction+1;

    #pragma omp parallel for
    for( int planeNr=0; planeNr < nrOfPlanes; planeNr++ )
    {
        IPLImagePlane* plane = image->plane( planeNr );
        IPLImagePlane* newplane = _result->plane( planeNr );
        {
            for(int y=0; y<height; y++)
            {
                // progress
                notifyProgressEventHandler(100*progress++/maxProgress);
                for(int x=0; x<width; x++)
                {
                    int dirCount = 0;
                    long sum = 0;
                    long total = 0;
                    for( int dir = startDir; dir<endDir; dir++ )
                    {
                        dirCount++;
                        sum = 0;
                        for( int kx=-1; kx<=1; kx++ )
                        {
                            for( int ky=-1; ky<=1; ky++ )
                            {
                                int mask = _mask[maskType][dir][ky+1][kx+1];
                                sum += (long) (plane->cp(x+kx, y+ky) * FACTOR_TO_UCHAR) * (long) mask;
                            }
                        }
                        total += sum;
                    }
                    total /= dirCount;
                    total += 128;
                    total = (total>255)? 255 : (total<0)? 0 : total;
                    newplane->p(x,y) = total * FACTOR_TO_FLOAT;
                }
            }
        }
    }
    return true;
}
示例#2
0
void IPLImage::fillColor(ipl_basetype value)
{
    for( int planeNr = 0; planeNr < _nrOfPlanes; planeNr++ )
    {
        IPLImagePlane* plane = _planes[planeNr];
        for( int x=0; x<_width; x++ )
            for( int y=0; y<_height; y++ )
                plane->p(x,y) = value;
    }
}
bool IPLMorphologyHitMiss::processInputData(IPLImage* image, int, bool)
{
    // delete previous result
    delete _result;
    _result = NULL;

    int width = image->width();
    int height = image->height();

    // copy constructor doesnt work:
    // _result = new IPLImage(*image);

    _result = new IPLImage( IPL_IMAGE_BW, width, height);

    // get properties
//    _propertyMutex.lock();
    _kernel     = getProcessPropertyVectorInt("kernel");
//    _propertyMutex.unlock();

    IPLImagePlane* inputPlane = image->plane( 0 );
    IPLImagePlane* resultPlane = _result->plane( 0 );

    IPLImagePlane* workingPlane = new IPLImagePlane(width, height);

    // the algorithm needs a working plane
    for(int x=0; x<width; x++)
    {
        for(int y=0; y<height; y++)
        {
            workingPlane->p(x,y) = inputPlane->p(x,y);
        }
    }


    _progress = 0;
    _maxProgress = image->height() * image->getNumberOfPlanes();

    hitmiss(workingPlane, resultPlane);

    return true;
}
示例#4
0
void applyMorphology(IPLImagePlane &src, IPLImagePlane &dst, int iterations, const std::vector<bool> &kernel, CB progressCallback)
{
    int kernelOffset = (int)sqrt((float)kernel.size()) / 2;

    for (int i = 0; i < iterations; ++i)
    {
        #pragma omp parallel for default(shared)
        for (int y = 0; y < src.height(); ++y)
        {
            for (int x = 0; x < src.width(); ++x)
            {
                //TODO: Speed up this routine
                //There would be several possibilities such as usage of SIMD techniques
                //or the reduction of the source image (e.g. to unsigned char)

                bool cancel = false;
                auto &pixelValue = dst.p(x,y);
                int i = 0;
                for( int ky=-kernelOffset; !cancel && ky<=kernelOffset; ky++ )
                {
                    for( int kx=-kernelOffset; !cancel && kx<=kernelOffset; kx++ )
                    {
                        if (   x+kx < 0 || x+kx >= src.width()
                            || y+ky < 0 || y+ky >= src.height())
                            continue;

                        auto &p = src.p(x+kx,y+ky);
                        bool mask = kernel[i++];
                        bool pixel = p == (float)T;
                        cancel = mask && pixel;
                    }
                }

                pixelValue = cancel? T : F;
            }
            progressCallback();
        }
        std::swap(src,dst);
    }
    std::swap(src,dst);
}
示例#5
0
bool IPLGabor::processInputData(IPLImage* image , int, bool)
{
    // delete previous result
    delete _result0;
    _result0 = NULL;
    delete _result1;
    _result1 = NULL;
    delete _result2;
    _result2 = NULL;

    int width = image->width();
    int height = image->height();
    _result0 = new IPLImage( image->type(), width, height );
    _result1 = new IPLImage( image->type(), width, height );
    _result2 = new IPLImage( image->type(), width, height );

    // get properties
    int window = getProcessPropertyInt("window");
    int wavelength = getProcessPropertyInt("wavelength");
    double direction = getProcessPropertyDouble("direction");
    double deviation = getProcessPropertyDouble("deviation");

    //int progress = 0;
    //int maxProgress = image->height() * image->getNumberOfPlanes();

    int w2 = window/2;
    int area = window*window;
    double* qEven = new double [area];
    double* qOdd = new double [area];

    double k = 2.0 * PI / (double) wavelength;
    double k2 = k * k;
    double d2 = deviation * deviation;
    double sig2 = 1.0 / (2.0 * d2);
    double kx = k * cos( direction );
    double ky = -k * sin( direction );

    int index = 0;
    double E = 0.0;
    double O =0.0;
    for( int x = -w2; x <= w2; x++ )
    {
        for( int y = -w2; y <= w2; y++)
        {
            double compensate = k2/d2;
            double envelope = exp( -k2 * sig2 * (x*x+y*y) );
            double DC = exp( -d2/2.0);
            E += qEven[index] = compensate * envelope * ( cos( kx*x + ky*y ) - DC );
            O += qOdd[index++]  = compensate * envelope * ( sin( kx*x + ky*y )- DC );
        }
    }

    for( int planeNr=0; planeNr < image->getNumberOfPlanes(); planeNr++ )
    {
        IPLImagePlane* plane        = image->plane( planeNr );
        IPLImagePlane* evenplane    = _result0->plane( planeNr );
        IPLImagePlane* oddplane     = _result1->plane( planeNr );
        IPLImagePlane* powerplane   = _result2->plane( planeNr );
        for(int x=w2; x<width-w2; x++)
        {
            for(int y=w2; y<height-w2; y++)
            {
                double even = 0;
                double odd = 0;
                double power = 0;
                int i = 0;
                for( int kx=-w2; kx<=w2; kx++ )
                {
                    for( int ky=-w2; ky<=w2; ky++ )
                    {
                        double img = (double) plane->p(x+kx, y+ky);
                        even += img * qEven[i];
                        odd  += img * qOdd[i++];
                    }
                }
                power = (even*even + odd*odd )*2;
                even = even  + 0.5;
                odd = odd + 0.5;
                even = (even>1.0)? 1.0 : (even<0)? 0 : even;
                odd = (odd>1.0)? 1.0 : (odd<0)? 0 : odd;
                power = (power>1.0)? 1.0 : (power<0)? 0 : power;
                evenplane->p(x,y)   =  even;
                oddplane->p(x,y)    = odd;
                powerplane->p(x,y)  =  power;
            }
        }
    }
    delete [] qEven;
    delete [] qOdd;

    return true;
}
bool IPLBlendImages::processInputData(IPLImage* image , int imageIndex, bool)
{
    // save the first image
    if(imageIndex == 0)
    {
        delete _inputA;
        _inputA = new IPLImage(*image);
    }

    // save the second image
    if(imageIndex == 1)
    {
        delete _inputB;
        _inputB = new IPLImage(*image);
    }

    // only continue if we have 2 valid inputs
    if(!(_inputA && _inputB))
    {
        return false;
    }

    // delete previous result
    delete _result;
    _result = NULL;

    // the result will be the max size of both inputs
    int width  = std::max(_inputA->width(), _inputB->width());
    int height = std::max(_inputA->height(), _inputB->height());

    // copy constructor doesnt work:
    // _result = new IPLImage(*image);

    // get properties
    _operation   = getProcessPropertyInt("operation");
    _factorA     = getProcessPropertyDouble("factorA");
    _factorB     = getProcessPropertyDouble("factorB");

    int maxNrOfPlanes = std::max( _inputA->getNumberOfPlanes(), _inputB->getNumberOfPlanes());
    int progress = 0;
    int maxProgress = maxNrOfPlanes*height;

    IPLDataType type = IPL_IMAGE_COLOR;
    if(maxNrOfPlanes == 1)
        type = IPL_IMAGE_GRAYSCALE;

    // create result
    _result = new IPLImage(type, width, height);

    #pragma omp parallel for
    for( int planeNr=0; planeNr < maxNrOfPlanes; planeNr++ )
    {
        // prevent reading unavailable planes
        IPLImagePlane* planeA   = _inputA->plane(std::min(planeNr, _inputA->getNumberOfPlanes()-1));
        IPLImagePlane* planeB   = _inputB->plane(std::min(planeNr, _inputB->getNumberOfPlanes()-1));
        IPLImagePlane* newplane = _result->plane(planeNr);

        for(int y=0; y<height; y++)
        {
            // progress
            notifyProgressEventHandler(100*progress++/maxProgress);

            for(int x=0; x<width; x++)
            {
                float valueA = _factorA * (float) planeA->cp(x,y);
                float valueB = _factorB * (float) planeB->cp(x,y);
                float value = 0.0f;

                switch (_operation) {
                case 1:
                    value = ChannelBlend_Lighten(valueA, valueB);
                    break;
                case 2:
                    value = ChannelBlend_Darken(valueA, valueB);
                    break;
                case 3:
                    value = ChannelBlend_Multiply(valueA, valueB);
                    break;
                case 4:
                    value = ChannelBlend_Average(valueA, valueB);
                    break;
                case 5:
                    value = ChannelBlend_Add(valueA, valueB);
                    break;
                case 6:
                    value = ChannelBlend_Subtract(valueA, valueB);
                    break;
                case 7:
                    value = ChannelBlend_Difference(valueA, valueB);
                    break;
                case 8:
                    value = ChannelBlend_Negation(valueA, valueB);
                    break;
                case 9:
                    value = ChannelBlend_Screen(valueA, valueB);
                    break;
                case 10:
                    value = ChannelBlend_Exclusion(valueA, valueB);
                    break;
                case 11:
                    value = ChannelBlend_Overlay(valueA, valueB);
                    break;
                case 12:
                    value = ChannelBlend_SoftLight(valueA, valueB);
                    break;
                case 13:
                    value = ChannelBlend_HardLight(valueA, valueB);
                    break;
                case 14:
                    value = ChannelBlend_ColorDodge(valueA, valueB);
                    break;
                case 15:
                    value = ChannelBlend_ColorBurn(valueA, valueB);
                    break;
                case 16:
                    value = ChannelBlend_LinearDodge(valueA, valueB);
                    break;
                case 17:
                    value = ChannelBlend_LinearBurn(valueA, valueB);
                    break;
                case 18:
                    value = ChannelBlend_LinearLight(valueA, valueB);
                    break;
                case 19:
                    value = ChannelBlend_VividLight(valueA, valueB);
                    break;
                case 20:
                    value = ChannelBlend_PinLight(valueA, valueB);
                    break;
                case 21:
                    value = ChannelBlend_HardMix(valueA, valueB);
                    break;
                case 22:
                    value = ChannelBlend_Reflect(valueA, valueB);
                    break;
                case 23:
                    value = ChannelBlend_Glow(valueA, valueB);
                    break;
                case 24:
                    value = ChannelBlend_Phoenix(valueA, valueB);
                    break;
                default:
                    value = ChannelBlend_Normal(valueA, valueB);
                    break;
                }

                // clamp to 0.0-1.0
                value = min(1.0f, max(0.0f, value));
                newplane->p(x,y) = value;
            }
        }
    }

    //_inputA = NULL;
    //_inputB = NULL;

    return true;
}
bool IPLBinarizeSavola::processInputData(IPLImage* image , int, bool)
{
    // delete previous result
    delete _result;
    _result = NULL;

    int width  = image->width();
    int height = image->height();

    _result = new IPLImage(image->type(), width, height);

    // get properties
    int window = getProcessPropertyInt("window");
    double aboveMean = getProcessPropertyDouble("aboveMean");


    IPLImage* mean = new IPLImage(image->type(), width, height);
    IPLImage* deviation = new IPLImage(image->type(), width, height);

    int progress = 0;
    int maxProgress = image->height() * image->getNumberOfPlanes();
    int nrOfPlanes = image->getNumberOfPlanes();

    #pragma omp parallel for
    for( int planeNr=0; planeNr < nrOfPlanes; planeNr++ )
    {
        IPLImagePlane* plane = image->plane( planeNr );
        IPLImagePlane* newplane = _result->plane( planeNr );

        int w2 = window/2;
        float area = (float)(w2*2)*(float)(w2*2);
        float minI = FLT_MAX;
        float maxDeviation = 0.0;

        for(int y=0; y<height; y++)
        {
            // progress
           notifyProgressEventHandler(100*progress++/maxProgress);

            for(int x=0; x<width; x++)
            {
                if( plane->p(x,y) < minI ) minI = plane->p(x,y);
                float localMean = 0.0;
                for( int kx=-w2; kx<=w2; kx++ )
                {
                    for( int ky=-w2; ky<=w2; ky++ )
                    {
                        localMean += (float)plane->cp(x+kx,y+ky);
                    }
                }
                localMean /= area;
                mean->plane(planeNr)->p(x,y) = localMean;

                float dev = 0.0;
                for( int kx=-w2; kx<=w2; kx++ )
                {
                    for( int ky=-w2; ky<=w2; ky++ )
                    {
                        float diff =  (float)plane->cp(x+kx, y+ky) - localMean;
                        dev += diff * diff;
                    }
                }
                dev = sqrt( dev / area );
                deviation->plane(planeNr)->p(x,y) = dev;
                if( dev > maxDeviation ) maxDeviation = dev;
            }

            for(int x=w2; x<width-w2; x++)
            {
                for(int y=w2; y<height-w2; y++)
                {
                    float alpha = 1.0 - deviation->plane(planeNr)->p(x,y) / maxDeviation;
                    int T = (int) ( mean->plane(planeNr)->p(x,y) - aboveMean * alpha *( mean->plane(planeNr)->p(x,y) - minI ) );
                    newplane->p(x,y) = ( plane->p(x,y) >= T ) ? 0.0 : 1.0;
                }
            }
        }
    }

    return true;
}
示例#8
0
bool IPLFFT::processInputData(IPLImage* image , int, bool)
{
    // delete previous result
    delete _result;
    _result = NULL;

    int width = image->width();
    int height = image->height();
    int cWidth = IPLComplexImage::nextPowerOf2(width);
    int cHeight = IPLComplexImage::nextPowerOf2(height);
    int size = cHeight = cWidth = (cWidth>cHeight)? cWidth : cHeight;

    _result = new IPLComplexImage(cWidth, cHeight);

    // get properties
    int mode = getProcessPropertyInt("mode");

    int progress = 0;
    int maxProgress = image->height() * image->getNumberOfPlanes();

    // image center
    int dx = ( cWidth - width )/2;
    int dy = ( cHeight - height )/2;

    IPLImagePlane* plane = image->plane(0);
    for(int y=0; y<height; y++)
    {
        // progress
        notifyProgressEventHandler(100*progress++/maxProgress);
        for(int x=0; x<width; x++)
        {
            _result->c(x+dx, y+dy) = Complex(plane->p(x,y), 0.0);
        }
    }

    // windowing function
    switch(mode)
    {
        case 0: // rectangular
                break;

        case 1: // Hanning
                for( int y=0; y<size; y++ )
                    for( int x=0; x<size; x++ )
                        _result->c(x,y) *= Hanning(x, size) * Hanning(y, size);
                break;
        case 2: // Hamming
                for( int y=0; y<size; y++ )
                    for( int x=0; x<size; x++ )
                        _result->c(x,y) *= Hamming(x, size) * Hamming(y, size);
                break;
        case 3: // Blackman
                for( int y=0; y<size; y++ )
                    for( int x=0; x<size; x++ )
                        _result->c(x,y) *= Blackman(x, size) * Blackman(y, size);
                break;
        case 4: // Border only
                int border = size / 32;
                for( int y=0; y<border; y++ )
                    for( int x=0; x<size; x++ )
                    {
                        double factor = (0.54 - 0.46 * cos( 2.0 * PI * y / border / 2.0 ));
                        _result->c(x,y) *= factor;
                        _result->c(x,size-y-1) *= factor;
                    }
                for( int x=0; x<border; x++ )
                    for( int y=0; y<size; y++ )
                    {
                        double factor = (0.54 - 0.46 * cos( 2.0 * PI * x / border / 2.0 ));
                        _result->c(x,y) *= factor;
                        _result->c(size-x-1,y) *= factor;
                    }
                break;
    }

    _result->FFT();

    return true;
}
示例#9
0
bool IPLLocalThreshold::processInputData(IPLImage* image , int, bool)
{
    // delete previous result
    delete _result;
    _result = NULL;

    int width = image->width();
    int height = image->height();

    if(image->type() == IPLImage::IMAGE_GRAYSCALE)
        _result = new IPLImage(IPLImage::IMAGE_BW, width, height);
    else
        _result = new IPLImage(image->type(), width, height);

    // get properties
    int window = getProcessPropertyInt("window");
    float aboveMean = getProcessPropertyDouble("aboveMean");

    int progress = 0;
    int maxProgress = image->height() * image->getNumberOfPlanes();
    int nrOfPlanes = image->getNumberOfPlanes();

    #pragma omp parallel for
    for( int planeNr=0; planeNr < nrOfPlanes; planeNr++ )
    {
        IPLImagePlane* plane = image->plane( planeNr );
        IPLImagePlane* newplane = _result->plane( planeNr );

        int w2 = window/2;
        double area = (double)window*(double)window;

        for(int y=w2; y < height-w2; y++)
        {
            // progress
            notifyProgressEventHandler(100*progress++/maxProgress);
            for(int x=w2; x < width-w2; x++)
            {
                double localMean = 0.0;
                for( int kx=-w2; kx<=w2; kx++ )
                {
                    for( int ky=-w2; ky<=w2; ky++ )
                    {
                        localMean += (double)plane->p(x+kx,y+ky);
                    }
                }
                localMean /= area;
                double deviation = 0.0;
                for( int kx=-w2; kx<=w2; kx++ )
                {
                    for( int ky=-w2; ky<=w2; ky++ )
                    {
                        double diff =  (double)plane->p(x+kx, y+ky) - localMean;
                        deviation += diff * diff;
                    }
                }
                deviation = sqrt( deviation / area );
                double T = (localMean + aboveMean*deviation);

                newplane->p(x,y) = (plane->p(x,y) >= T) ? 1.0 : 0.0;
            }
        }
    }
    return true;
}
bool IPLMorphologicalEdge::processInputData(IPLImage* image , int, bool)
{
    // delete previous result
    delete _result;
    _result = NULL;

    int width = image->width();
    int height = image->height();
    _result = new IPLImage( image->type(), width, height );

    // get properties
    int window = getProcessPropertyInt("window");

    int progress = 0;
    int maxProgress = image->height() * image->getNumberOfPlanes() * 2;
    int nrOfPlanes = image->getNumberOfPlanes();

    int w2 = window/2;
    int area = window*window;

    #pragma omp parallel for
    for( int planeNr=0; planeNr < nrOfPlanes; planeNr++ )
    {
        IPLImagePlane* plane = image->plane( planeNr );
        IPLImagePlane* newplane = _result->plane( planeNr );
        IPLImagePlane* average = new IPLImagePlane(width, height);

        for(int x=w2; x<width-w2; x++)
        {
            // progress
            notifyProgressEventHandler(100*progress++/maxProgress);
            for(int y=w2; y<height-w2; y++)
            {
                ipl_basetype sum = 0;
                for( int kx=-w2; kx<=w2; kx++ )
                {
                    for( int ky=-w2; ky<=w2; ky++ )
                    {
                        if( kx || ky ) sum += plane->p(x+kx, y+ky);
                    }
                }
                average->p(x,y) = sum;
            }
        }
        for(int x=w2; x<width-w2; x++)
        {
            // progress
            notifyProgressEventHandler(100*progress++/maxProgress);

            for(int y=w2; y<height-w2; y++)
            {
                float minc = (area-1);
                float maxc = 0;
                for( int kx=-w2; kx<=w2; kx++ )
                {
                    for( int ky=-w2; ky<=w2; ky++ )
                    {
                        ipl_basetype img = average->bp(x+kx, y+ky);
                        if( img > maxc) maxc = img;
                        if( img < minc) minc = img;
                    }
                }
                ipl_basetype img = average->p(x,y);
                ipl_basetype d1 = img - minc;
                ipl_basetype d2 = maxc - img;
                ipl_basetype min = (d1 < d2)? d1 : d2;
                min = (min<1.0)? min : 1.0;
                min = (min>0.0)? min : 0.0;
                newplane->p(x,y) = min;
            }
        }
        delete average;
    }
    return true;
}
bool IPLBinarizeUnimodal::processInputData(IPLImage* image , int, bool)
{
    // delete previous result
    delete _result;
    _result = NULL;

    int width = image->width();
    int height = image->height();
    if( image->type() == IPL_IMAGE_GRAYSCALE )
        _result = new IPLImage( IPL_IMAGE_BW, width, height );
    else
        _result = new IPLImage( image->type(), width, height );

    int progress = 0;
    int maxProgress = image->height() * image->getNumberOfPlanes();
    int nrOfPlanes = image->getNumberOfPlanes();

    #pragma omp parallel for
    for( int planeNr=0; planeNr < nrOfPlanes; planeNr++ )
    {
        IPLImagePlane* plane = image->plane( planeNr );
        IPLImagePlane* newplane = _result->plane( planeNr );

        int p[256] = { 0 };

        for( int y = 0; y < height; ++y )
        {
            for( int x = 0; x < width; ++x )
            {
                int index = plane->p(x,y) * 255;
                p[index]++;
            }
        }

        // determine maxEntry
        int maxBin = 0;
        int maxFrequency = 0;
        for( int k=1; k<255; ++k )
        {
            if( p[k] > maxFrequency )
            {
                maxFrequency = p[k];
                maxBin = k;
            }
        }

        // determine zeroEntry
        int zeroBin = 0;
        int x0, x1;
        if( maxBin >= 128 )
        {
            zeroBin = 0;
            while( p[zeroBin]==0 ) ++zeroBin;
            x0 = zeroBin;
            x1 = maxBin;
        }
        else
        {
            zeroBin = 255;
            while( p[zeroBin]==0 ) --zeroBin;
            x0 = maxBin;
            x1 = zeroBin;
        }

        int y0 = p[x0];
        int y1 = p[x1];
        double a = y0 - y1;
        double b = x1 - x0;
        double c = x0*y1 - x1*y0;
        double d = sqrt( a*a + b*b );

        int T = 0;
        if( d != 0.0 )
        {
            double maxDist = 0.0;
            for( int k=x0; k<=x1; ++k )
            {
                double distance = std::abs( ( a*k + b*p[k] + c ) / d );
                if( distance > maxDist )
                {
                    maxDist = distance;
                    T = k;
                }
            }
        }

        ipl_basetype threshold = T * FACTOR_TO_FLOAT;

        std::stringstream s;
        s << "Automatic Threshold: ";
        s << threshold;
        addInformation(s.str());

        for(int y = 0; y < height; y++)
        {            // progress
            notifyProgressEventHandler(100*progress++/maxProgress);
            for(int x = 0; x < width; x++)
            {
                newplane->p(x,y)= (plane->p(x,y) > threshold)? 1.0 : 0.0;
            }
        }
    }
    return true;
}
示例#12
0
bool IPLCanvasSize::processInputData(IPLImage* image , int, bool)
{
    // delete previous result
    delete _result;
    _result = NULL;
    int width  = image->width();
    int height = image->height();

    _result = new IPLImage(image->type(), width, height);

    // get properties
    int         new_width   = getProcessPropertyInt("width");
    int         new_height  = getProcessPropertyInt("height");
    IPLColor    color       = getProcessPropertyColor("color");
    int         anchor      = getProcessPropertyInt("anchor");

    _result = new IPLImage(image->type(), new_width, new_height);

    int progress = 0;
    int maxProgress = image->height() * image->getNumberOfPlanes();
    int nrOfPlanes = _result->getNumberOfPlanes();

    //Anchor:Top Left|Top|Top Right|Left|Center|Right|Bottom Left|Bottom|Bottom Right

    // Top Left
    int offset_x = 0;
    int offset_y = 0;
    if(anchor == 1)
    {
        // Top
        offset_x = (new_width-width) * 0.5;
        offset_y = 0;
    }
    else if(anchor == 2)
    {
        // Top Right
        offset_x = new_width-width;
        offset_y = 0;
    }
    else if(anchor == 3)
    {
        // Left
        offset_x = 0;
        offset_y = (new_height-height) * 0.5;
    }
    else if(anchor == 4)
    {
        // Center
        offset_x = (new_width-width) * 0.5;
        offset_y = (new_height-height) * 0.5;
    }
    else if(anchor == 5)
    {
        // Right
        offset_x = new_width-width;
        offset_y = (new_height-height) * 0.5;
    }
    else if(anchor == 6)
    {
        // Bottom Left
        offset_x = 0;
        offset_y = new_height-height;
    }
    else if(anchor == 7)
    {
        // Bottom
        offset_x = (new_width-width) * 0.5;
        offset_y = new_height-height;
    }
    else if(anchor == 8)
    {
        // Bottom Right
        offset_x = new_width-width;
        offset_y = new_height-height;
    }

    if(nrOfPlanes == 1)
    {
        addWarning("For grayscale images, the red slider is used as background value.");
    }

    #pragma omp parallel for
    for( int planeNr=0; planeNr < nrOfPlanes; planeNr++ )
    {
        IPLImagePlane* plane = image->plane( planeNr );
        IPLImagePlane* newplane = _result->plane( planeNr );
        ipl_basetype background = 0.0;

        if(planeNr == 0)
            background = color.red();
        else if(planeNr == 1)
            background = color.green();
        if(planeNr == 2)
            background = color.blue();

        for(int y=0; y<new_height; y++)
        {
            // progress
           notifyProgressEventHandler(100*progress++/maxProgress);

            for(int x=0; x<new_width; x++)
            {
                int from_x = x - offset_x;
                int from_y = y - offset_y;

                // check if inside source image
                if(from_x < 0 || from_y < 0 || from_x > plane->width() || from_y > plane->height())
                {
                    newplane->p(x, y) = background;
                }
                else
                {
                    newplane->p(x, y) = plane->p(from_x, from_y);
                }
            }
        }
    }

    return true;
}
示例#13
0
bool IPLMedian::processInputData(IPLImage* image , int, bool useOpenCV)
{
    // delete previous result
    delete _result;
    _result = NULL;

    int width = image->width();
    int height = image->height();

    // get properties
    int window = getProcessPropertyInt("window");

    int progress = 0;
    int maxProgress = image->height() * image->getNumberOfPlanes();
    int nrOfPlanes = image->getNumberOfPlanes();

    int w2 = window/2;
    int area = window*window;

    if (!useOpenCV)
    {
        _result = new IPLImage( image->type(), width, height );

        #pragma omp parallel for
        for( int planeNr=0; planeNr < nrOfPlanes; planeNr++ )
        {
            IPLImagePlane* plane = image->plane( planeNr );
            IPLImagePlane* newplane = _result->plane( planeNr );

            ipl_basetype* list = new ipl_basetype[area];

            for(int y=0; y<height; y++)
            {
                // progress
                notifyProgressEventHandler(100*progress++/maxProgress);

                for(int x=0; x<width; x++)
                {
                    int i =0;
                    for( int ky=-w2; ky<=w2; ky++ )
                    {
                        for( int kx=-w2; kx<=w2; kx++ )
                        {
                            list[i++] = plane->bp(x+kx, y+ky);
                        }
                    }

                    // insert sort list
                    for( int k=area; k>=0; k--)
                    {
                        int j = k+1;
                        ipl_basetype temp = list[k];
                        while( j < area && temp > list[j] )
                        {
                            list[j-1] = list[j];
                            j++;
                        }
                        list[j-1] = temp;
                    }
                    newplane->p(x,y) = list[area/2];
                }
            }
        }
    }
    else
    {
        notifyProgressEventHandler(-1);

        auto src = image->toCvMat();
        cv::Mat dst;

        cv::medianBlur(src,dst,window);
        _result = new IPLImage(dst);
    }
    return true;
}
示例#14
0
bool IPLSynthesize::processInputData(IPLImage*, int, bool)
{
    if(isResultReady())
    {
        //return true;
    }

    // delete previous result
    delete _result;
    _result = NULL;

    // get properties
    _type       = getProcessPropertyInt("type");
    _width      = getProcessPropertyInt("width");
    _height     = getProcessPropertyInt("height");
    _amplitude  = getProcessPropertyDouble("amplitude");
    _offset     = getProcessPropertyDouble("offset");
    _wavelength = getProcessPropertyInt("wavelength");
    _direction  = getProcessPropertyInt("plane_direction");
    _decay      = getProcessPropertyInt("decay");

    IPLColor color = getProcessPropertyColor("flat_color");

    if( _type == 0 )
        _result = new IPLImage( IPL_IMAGE_COLOR, _width, _height );
    else
        _result = new IPLImage( IPL_IMAGE_GRAYSCALE, _width, _height );

    double dx = (double)_width / 2.0;
    double dy = (double)_height / 2.0;
    double direction = _direction / 180.0 * PI; // deg to rad

    IPLImagePlane* plane = _result->plane( 0 );

    int progress = 0;
    int maxProgress = _result->height();

    switch( _type )
    {
    case 0: // flat plane
        for( int y=0; y<_height; y++ )
        {
            notifyProgressEventHandler(100*progress++/maxProgress);
            for( int x=0; x<_width; x++ )
            {
                _result->plane(0)->p(x,y) = color.red();
                _result->plane(1)->p(x,y) = color.green();
                _result->plane(2)->p(x,y) = color.blue();
            }
        }
        break;
    case 1: // plane wave
        for( int y=0; y<_height; y++ )
        {
            notifyProgressEventHandler(100*progress++/maxProgress);
            for( int x=0; x<_width; x++ )
            {
                double dist = (x)*cos( direction ) + (_height-y)*sin( direction );
                double fade = (_decay!=0) ? exp( -dist/_decay ) : 1.0;
                double value = _amplitude * cos(dist/_wavelength * PI * 2.0) * fade + _offset;
                plane->p(x,y) = ( (value<0.0)? 0.0 : (value>1.0)? 1.0 : value );
            }
        }
        break;
    case 2:// center wave
        for( int y=0; y<_height; y++ )
        {
            notifyProgressEventHandler(100*progress++/maxProgress);
            for( int x=0; x<_width; x++ )
            {
                double dist = sqrt( (x-dx)*(x-dx) + (y-dy)*(y-dy) );
                double fade = (_decay!=0) ? exp( -dist/_decay ) : 1.0;
                double value = _amplitude * cos( dist/_wavelength * PI * 2.0 ) * fade + _offset;
                plane->p(x,y) = ( (value<0.0)? 0.0 : (value>1.0)? 1.0 : value );
            }
        }
        break;
    }

    return true;
}
bool IPLConvolutionFilter::processInputData(IPLImage* image , int, bool useOpenCV)
{
    // delete previous result
    delete _result;
    _result = NULL;

    int width = image->width();
    int height = image->height();

    // get properties
    _kernel     = getProcessPropertyVectorInt("kernel");
    _divisor    = getProcessPropertyInt("divisor");
    _offset     = getProcessPropertyDouble("offset");
    _normalize  = getProcessPropertyBool("normalize");
    _borders    = getProcessPropertyInt("borders");

    if(_normalize)
    {
        int sum = 0;
        for(size_t i=0; i<_kernel.size(); i++)
        {
            sum += _kernel[i];
        }
        _divisor = (sum != 0 ? sum : 1);
    }

    if (_divisor == 0)
    {
        addError("Invalid divisor: 0");
        return false;
    }

    float divFactor = 1.0f/_divisor;

    int kernelWidth = (int)sqrt((float)_kernel.size());
    int kernelOffset = kernelWidth / 2;

    int progress = 0;
    int maxProgress = image->height() * image->getNumberOfPlanes();

    if (!useOpenCV)
    {
        _result = new IPLImage( image->type(), width, height );
        #pragma omp parallel for default(shared)
        for( int planeNr=0; planeNr < image->getNumberOfPlanes(); planeNr++ )
        {
            IPLImagePlane* plane = image->plane( planeNr );
            IPLImagePlane* newplane = _result->plane( planeNr );

            for(int y=0; y<plane->height(); y++)
            {
                // progress
                notifyProgressEventHandler(100*progress++/maxProgress);

                for(int x=0; x<plane->width(); x++)
                {
                    float sum = 0;
                    int i = 0;
                    for( int ky=-kernelOffset; ky<=kernelOffset; ky++ )
                    {
                        for( int kx=-kernelOffset; kx<=kernelOffset; kx++ )
                        {
                            int h = _kernel[i++];
                            if( h )
                            {
                                if(_borders == 0)
                                {
                                    // Crop borders
                                    sum += plane->cp(x+kx, y+ky) * h;
                                }
                                else if(_borders == 1)
                                {
                                    // Extend borders
                                    sum += plane->bp(x+kx, y+ky) * h;
                                } else {
                                    // Wrap borders
                                    sum += plane->wp(x+kx, y+ky) * h;
                                }
                            }
                        }
                    }
                    sum = sum * divFactor + _offset;
                    sum = (sum>1.0) ? 1.0 : (sum<0) ? 0.0 : sum; // clamp to 0.0 - 1.0
                    newplane->p(x,y) = sum;
                }
            }
        }
    }
    else
    {
        notifyProgressEventHandler(-1);

        cv::Mat src = image->toCvMat();
        cv::Mat dst;
        cv::Mat kernel(kernelWidth, kernelWidth, CV_32FC1 );

        int i = 0;
        for( int y=0; y < kernelWidth; y++ )
            for( int x=0; x < kernelWidth; x++ )
                kernel.at<float>(cv::Point(x,y)) = _kernel[i++];

        kernel *= divFactor;

        static const int BORDER_TYPES[3] = {
          cv::BORDER_CONSTANT,
          cv::BORDER_REPLICATE,
          cv::BORDER_WRAP
        };

        cv::filter2D(src, dst, -1, kernel, cv::Point(-1,-1), _offset, BORDER_TYPES[_borders]);
        _result = new IPLImage(dst);
    }

    return true;
}
示例#16
0
bool IPLCanny::processInputData(IPLImage* image , int, bool useOpenCV)
{
    // delete previous result
    delete _result;
    _result = NULL;
    delete _binaryImage;
    _binaryImage = NULL;

    int width = image->width();
    int height = image->height();

    _result = new IPLImage( image->type(), width, height );
    _binaryImage = new IPLImage( IPLData::IMAGE_BW, width, height );

    // get properties
    int window              = getProcessPropertyInt("window");
    double sigma            = getProcessPropertyDouble("sigma");
    double lowThreshold     = getProcessPropertyDouble("lowThreshold");
    double highThreshold    = getProcessPropertyDouble("highThreshold");

    std::stringstream s;
    s << "Window: ";
    s << window;
    addInformation(s.str());

    //! @todo currently only the opencv implementation works
    if(useOpenCV || true)
    {
        notifyProgressEventHandler(-1);
        cv::Mat input;
        cv::Mat output;
        cvtColor(image->toCvMat(), input, CV_BGR2GRAY);
        cv::Canny(input, output, lowThreshold*255, highThreshold*255, window);

        delete _result;
        _result = new IPLImage(output);

        return true;
    }

    return false;

    // Create a Gaussian 1D filter
    int N = ceil( sigma * sqrt( 2.0*log( 1.0/0.015 ) ) + 1.0 );
    double ssq = sigma*sigma;
    double* gau = new double [window];
    double* dgau = new double [window];
    for( int k = -N; k <= N; ++k )
    {
        gau[k+N] = gauss ( (double)k, ssq );
        dgau[k+N] = dGauss ( (double)k, 0, ssq );
    }

    // Create a directional derivative of 2D Gaussian (along X-axis)
    // Since the result is symmetric along X, we can get the derivative along
    // Y-axis simply by transposing the result for X direction.
//		DoubleImage* dgau = new DoubleImage( window, window );
//		for( int y = -N; y <= N; ++y )
//			for( int x = -N; x <= N; ++x )
//				dgau->f(x+N, y+N) = dGauss( x, y, ssq );

    int progress = 0;
    int maxProgress = width * image->getNumberOfPlanes();
    int nrOfPlanes = image->getNumberOfPlanes();

    //#pragma omp parallel for
    for( int planeNr=0; planeNr < nrOfPlanes; planeNr++ )
    {
        IPLImagePlane* plane = image->plane( planeNr );
        IPLImagePlane* newplane = _result->plane( planeNr );

// ******** Gaussian filtering of input image
        IPLImagePlane* gI = new IPLImagePlane( width, height );

        // horizontal run (normalizing original image)
        IPLImagePlane* tmpI = new IPLImagePlane( width, height );
        for(int x=0; x<width; x++)
        {            // progress
            notifyProgressEventHandler(100*progress++/maxProgress);

            for(int y=0; y<height; y++)
            {
                double sum = 0;
                int i = 0;
                for( int kx=-N; kx<=N; kx++ )
                {
                        double img = (double) plane->bp(x+kx, y);
                        sum += (img * gau[i++]);
                }
                tmpI->p(x,y) = (double) (sum);
            }
        }
        // vertiacl run
        for(int x=0; x<width; x++)
        {
            for(int y=0; y<height; y++)
            {
                double sum = 0;
                int i = 0;
                for( int ky=-N; ky<=N; ky++ )
                {
                        double img = tmpI->bp(x, y+ky);
                        sum += (img * gau[i++]);
                }
                gI->p(x,y) = sum;
            }
        }
        //delete tmpI;

// ******** Apply directional derivatives ...

        // ... in x-direction
        IPLImagePlane* dx = new IPLImagePlane( width, height );
        for(int x=0; x<width; x++)
        {
            for(int y=0; y<height; y++)
            {
                dx->p(x,y) = 0.0;
                for( int k=1; k<N; k++ )
                {
                    dx->p(x,y) += ( gI->bp(x-k,y) - gI->bp(x+k,y) ) * dgau[k];
                }
            }
        }
//			double maxVal = 0.0;
//			for(int x=0; x<width; x++)
//				for(int y=0; y<height; y++)
//					if( dx->f(x,y) > maxVal ) maxVal = dx->f(x,y);

        // ... in y-direction
        IPLImagePlane* dy = new IPLImagePlane( width, height );
        for(int x=0; x<width; x++)
        {
            for(int y=0; y<height; y++)
            {
                dy->p(x,y) = 0.0;
                for( int k=1; k<N; k++ )
                {
                    dy->p(x,y) += ( gI->bp(x,y-k) - gI->bp(x,y+k) ) * dgau[k];
                }
            }
        }

// ******** Compute magnitude and binarization thresholds
        IPLImagePlane* mag = new IPLImagePlane( width, height );
        double magMax = 0.0;
        double magMin = 999999999.0;
        for(int x=0; x<width; x++)
        {
            for(int y=0; y<height; y++)
            {
                double val = sqrt( dx->p(x,y)*dx->p(x,y) + dy->p(x,y)*dy->p(x,y) );
                mag->p(x,y) = val;
                if( val > magMax ) magMax = val;
                if( val < magMin ) magMin = val;
            }
        }

//// ******** Non-maxima suppression - edge pixels should be a local maximum
        _orientedImage = new IPLOrientedImage( width, height );
        for(int x=0; x<width; x++)
        {
            for(int y=0; y<height; y++)
            {
                double ix = dx->p(x,y);
                double iy = dy->p(x,y);
                double g = mag->p(x,y);

                // determine 4-neighbor direction of gradient
                int dir4 = 0;
                if( (iy<=0.0 && ix>-iy) || (iy>=0.0 && ix<-iy) )
                    dir4 = 1;
                else if( (ix>0.0 && -iy>=ix) || (ix<0.0 && -iy<=ix) )
                    dir4 = 2;
                else if( (ix<=0.0 && ix>iy) || (ix>=0.0 && ix<iy) )
                    dir4 = 3;
                else if( (iy<0.0 && ix<=iy) || (iy>0.0 && ix>=iy) )
                    dir4 = 4;
                else
                    continue;

                double gradmag1, gradmag2, d;
                switch(dir4)
                {
                    case 1: d = std::fabs(iy/ix);
                            gradmag1 = mag->bp(x+1,y)*(1-d) + mag->bp(x+1,y-1)*d;
                            gradmag2 = mag->bp(x-1,y)*(1-d) + mag->bp(x-1,y+1)*d;
                            break;
                    case 2: d = std::fabs(ix/iy);
                            gradmag1 = mag->bp(x,y-1)*(1-d) + mag->bp(x+1,y-1)*d;
                            gradmag2 = mag->bp(x,y+1)*(1-d) + mag->bp(x-1,y+1)*d;
                            break;
                    case 3: d = std::fabs(ix/iy);
                            gradmag1 = mag->bp(x,y-1)*(1-d) + mag->bp(x-1,y-1)*d;
                            gradmag2 = mag->bp(x,y+1)*(1-d) + mag->bp(x+1,y+1)*d;
                            break;
                    case 4: d = std::fabs(iy/ix);
                            gradmag1 = mag->bp(x-1,y)*(1-d) + mag->bp(x-1,y-1)*d;
                            gradmag2 = mag->bp(x+1,y)*(1-d) + mag->bp(x+1,y+1)*d;
                            break;
                }

                if( g > gradmag1 && g > gradmag2 )
                {
                    _orientedImage->magnitude(x,y) = g;
                    _orientedImage->phase(x,y) = atan2(iy,ix);
                }
            }

        }


        for(int x=0; x<width; x++)
        {
            for(int y=0; y<height; y++)
            {
                _orientedImage->magnitude(x,y) /= magMax;
                double val = _orientedImage->magnitude(x,y)*255.0;
//					double val = mag->f(x,y)/magMax*255.0;
                if (val > 255.0 ) val = 255.0;
                if (val < 0.0 ) val = 0.0;
                newplane->p(x,y) = (unsigned char ) val;
            }
        }

// ******** Binarize with hysteresis threshold
        double hist[ 256 ];
        for( int i=0; i<256; ++i )
            hist[i] = 0;
        int pixCount = 0;
        for(int x=0; x<width; x++)
        {
            for(int y=0; y<height; y++)
            {
                if( _orientedImage->magnitude(x,y) > 0.0 )
                {
                    int index = floor( _orientedImage->magnitude(x,y)*256.0+0.5 );
                    ++hist[ index ];
                    ++pixCount;
                }
            }
        }
        double PercentOfPixelsNotEdges = 0.7*pixCount;
        double highThresh = 0.0;
        double cumsum = 0.0;
        for( int i=0; i<256; ++i )
        {
            cumsum += hist[i];
            if( cumsum > PercentOfPixelsNotEdges )
            {
                highThresh = (double)i / 256.0;
                break;
            }
        }
        double lowThresh = 0.4 * highThresh;
        IPLImagePlane* binPlane = _binaryImage->plane( 0 );
        for(int x=0; x<width; x++)
        {
            for(int y=0; y<height; y++)
            {
                if(_orientedImage->magnitude(x,y) >= highThresh)
                    trace(x, y, lowThresh, _orientedImage, binPlane);
            }
        }
        //delete dx;
        //delete dy;
        //delete gI;

        thinning(_orientedImage, binPlane, newplane );
    }

    //delete [] gau;
    //delete [] dgau;

    return true;
}