示例#1
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);
}
示例#2
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;
}
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;
}