Пример #1
0
bool IPLUndistort::processInputData(IPLImage* image, int, bool)
{
    // get properties
    float k1 = getProcessPropertyDouble("k1");
    float k2 = getProcessPropertyDouble("k2");
    float k3 = getProcessPropertyDouble("k3");
    float p1 = getProcessPropertyDouble("p1");
    float p2 = getProcessPropertyDouble("p2");

    float c1 = getProcessPropertyInt("f");
    float c2 = c1;

    notifyProgressEventHandler(-1);

    cv::Mat cameraMatrix = (cv::Mat_<double>(3,3) << c1, 0, image->width()*0.5, 0, c2, image->height()*0.5, 0, 0, 1);


    cv::Mat distCoeffs(5, 1, CV_32FC1);
    distCoeffs.at<float>(0,0) = k1;
    distCoeffs.at<float>(1,0) = k2;
    distCoeffs.at<float>(2,0) = p1;
    distCoeffs.at<float>(3,0) = p2;
    distCoeffs.at<float>(4,0) = k3;

    cv::Mat result;
    cv::undistort(image->toCvMat(), result, cameraMatrix, distCoeffs);

    delete _result;
    _result = new IPLImage(result);

    return true;
}
Пример #2
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;
}
Пример #3
0
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;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #7
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;
}