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; }
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; }
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; }