void OOFImage3D::normalize() { padImage(-1); vtkImageData *alpha = getAlpha(); vtkImageAppendComponents *appender; vtkImageExtractComponents *extractor[3]; vtkImageMathematics *adder[3], *mult[3]; double *minmax, K; appender = vtkImageAppendComponents::New(); for(int i=0; i<3; i++) { extractor[i] = vtkImageExtractComponents::New(); extractor[i]->SetInputConnection(image->GetProducerPort()); extractor[i]->SetComponents(i); extractor[i]->Update(); minmax = extractor[i]->GetOutput()->GetScalarRange(); adder[i] = vtkImageMathematics::New(); adder[i]->SetInputConnection(extractor[i]->GetOutputPort()); adder[i]->SetOperationToAddConstant(); if(minmax[0] > 0 && minmax[0] != minmax[1]) { adder[i]->SetConstantC(256-minmax[0]); } else{ adder[i]->SetConstantC(0); } mult[i] = vtkImageMathematics::New(); mult[i]->SetInputConnection(adder[i]->GetOutputPort()); mult[i]->SetOperationToMultiplyByK(); if(minmax[0]!=minmax[1]) { K = 255.0/(minmax[1]-minmax[0]); mult[i]->SetConstantK(K); } else { mult[i]->SetConstantK(1.0); } mult[i]->GetOutput()->SetScalarTypeToUnsignedChar(); appender->AddInputConnection(mult[i]->GetOutputPort()); } appender->AddInputConnection(alpha->GetProducerPort()); image = appender->GetOutput(); padImage(1); imageChanged(); }
OOFImage3D::OOFImage3D(const std::string &name, const ICoord &isize, const std::vector<unsigned short> *data) : name_(name) { image = vtkImageData::New(); image->SetDimensions(isize(0),isize(1),isize(2)); image->SetScalarTypeToUnsignedChar(); image->SetNumberOfScalarComponents(3); image->AllocateScalars(); int i,j,k; for (i=0; i<isize(0); i++) { for (j=0; j<isize(1); j++) { for (k=0; k<isize(2); k++) { image->SetScalarComponentFromFloat(i,j,k,0, (float)((*data)[3*(i*(isize(1))*(isize(2))+j*isize(2)+k)])); image->SetScalarComponentFromFloat(i,j,k,1, (float)((*data)[3*(i*(isize(1))*(isize(2))+j*isize(2)+k)+1])); image->SetScalarComponentFromFloat(i,j,k,2, (float)((*data)[3*(i*(isize(1))*(isize(2))+j*isize(2)+k)+2])); } } } image->Update(); image = getRGBA(); padImage(1); setup(); }
// compute the gradients orientations and magnitudes for an image void cv::base::computeGradients(const cv::Mat& image, cv::Mat_<float>* x_grad, cv::Mat_<float>* y_grad, cv::Mat_<float>* thetas, cv::Mat_<float>* mags) { int fx[] = { -1, 0, 1 }; int fy[] = { -1, 0, 1 }; cv::Mat local_image; padImage(image, &local_image, 1, 1); *x_grad = cv::Mat(image.rows, image.cols, CV_32FC1); *y_grad = cv::Mat(image.rows, image.cols, CV_32FC1); *thetas = cv::Mat(image.rows, image.cols, CV_32FC1); *mags = cv::Mat(image.rows, image.cols, CV_32FC1); for (int y = 0; y < x_grad->rows; ++y) { const uchar* src_ptr = local_image.ptr<uchar>(y); float* dst_ptr_x = x_grad->ptr<float>(y); float* dst_ptr_y = y_grad->ptr<float>(y); float* dst_ptr_t = thetas->ptr<float>(y); float* dst_ptr_m = mags->ptr<float>(y); for (int x = 0; x < x_grad->cols; ++x) { *dst_ptr_x = 0.5f * (fx[0] * (*(src_ptr)) + fx[1] * (*(src_ptr + 1)) + fx[2] * (*(src_ptr + 2))); *dst_ptr_y = 0.5f * (fy[0] * (*(src_ptr)) + fy[1] * (*(src_ptr + local_image.cols)) + fy[2] * (*(src_ptr + 2 * local_image.cols))); *dst_ptr_t++ = atan2(*(dst_ptr_y), *(dst_ptr_x)); *dst_ptr_m++ = sqrt((*(dst_ptr_x))*(*(dst_ptr_x)) + (*(dst_ptr_y))*(*(dst_ptr_y))); dst_ptr_x++; dst_ptr_y++; src_ptr++; } } }
void OOFImage3D::flip(const std::string &axis) { padImage(-1); vtkImageFlip *flipper[3]; for(int i=0; i<axis.size(); i++) { flipper[i] = vtkImageFlip::New(); flipper[i]->SetFilteredAxis((int)axis[i]-(int)'x'); flipper[i]->SetInputConnection(image->GetProducerPort()); image = flipper[i]->GetOutput(); } image->Update(); padImage(1); imageChanged(); }
void OOFImage3D::medianFilter(int radius) { padImage(-1); vtkImageData *rgb = getRGB(); vtkImageData *alpha = getAlpha(); vtkImageMedian3D *median; median = vtkImageMedian3D::New(); median->SetKernelSize(radius*2, radius*2, radius*2); median->SetInputConnection(rgb->GetProducerPort()); rgb = median->GetOutput(); rgb->Update(); combineChannels(rgb,alpha); padImage(1); imageChanged(); }
void OOFImage3D::blur(double radius, double sigma) { vtkImageGaussianSmooth *gauss; padImage(-1); gauss = vtkImageGaussianSmooth::New(); gauss->SetRadiusFactors(radius, radius, radius); gauss->SetStandardDeviation(sigma, sigma, sigma); gauss->SetInputConnection(image->GetProducerPort()); image = gauss->GetOutput(); padImage(1); imageChanged(); }
// For now, save just writes the slices as pnms. We // might want to implement different formats later, but for now, this // is a sensible default since it's something we can read in easily. void OOFImage3D::save(const std::string &filepattern) { vtkPNMWriter *writer; writer = vtkPNMWriter::New(); padImage(-1); vtkImageData *rgb = getRGB(); writer->SetFilePattern(filepattern.c_str()); writer->SetInputConnection(rgb->GetProducerPort()); writer->Update(); writer->Write(); }
Image *ImageProcessing::convolve(Image *input_image, Image *kernel) { ///Check if the input image is valid if (!input_image || !kernel) return 0x00; ///Get the range of the input image Color *range = new Color[2]; range = input_image->range(); //std::cout << range[0] << std::endl; //std::cout << range[1] << std::endl; ///Kernel size is 2k + 1 int kernel_half_sizex = (kernel->getWidth() - 1)/2; int kernel_half_sizey = (kernel->getHeight() - 1)/2; ///Make the image into a square int max_dim = std::max(input_image->getWidth(), input_image->getHeight()); Image *squared_input_image = new Image(max_dim, max_dim, 0.0f, 0.0f, 0.0f,1.0f); for (int y=0;y<input_image->getHeight();y++) { for (int x=0;x<input_image->getWidth();x++) { squared_input_image->setPixel(x,y,input_image->getPixel(x,y)); } } Image * padded_input_image = padImage(squared_input_image, kernel_half_sizex, kernel_half_sizey); ///Perform the DFT on the image fftw_complex *dft_image_red = dft(padded_input_image, 0, false, -1, -1); fftw_complex *dft_image_green = dft(padded_input_image, 1, false, -1, -1); fftw_complex *dft_image_blue = dft(padded_input_image, 2, false, -1, -1); ///Perform the DFT on the kernel. Make sure the padding is set to 0 and it's the same size as the image fftw_complex *dft_kernel_red = dft(kernel, 0, true, padded_input_image->getWidth(), padded_input_image->getHeight()); fftw_complex *dft_kernel_green = dft(kernel, 1, true, padded_input_image->getWidth(), padded_input_image->getHeight()); fftw_complex *dft_kernel_blue = dft(kernel, 2, true, padded_input_image->getWidth(), padded_input_image->getHeight()); ///Multiply the two together for (int k=0,y=0;y<padded_input_image->getHeight();y++) { for (int x=0;x<padded_input_image->getWidth();x++,k++) { float red_val1 = dft_image_red[k][0] * dft_kernel_red[k][0] - dft_image_red[k][1] * dft_kernel_red[k][1]; float red_val2 = dft_image_red[k][0] * dft_kernel_red[k][1] + dft_image_red[k][1] * dft_kernel_red[k][0]; dft_image_red[k][0] = red_val1; dft_image_red[k][1] = red_val2; float green_val1 = dft_image_green[k][0] * dft_kernel_green[k][0] - dft_image_green[k][1] * dft_kernel_green[k][1]; float green_val2 = dft_image_green[k][0] * dft_kernel_green[k][1] + dft_image_green[k][1] * dft_kernel_green[k][0]; dft_image_green[k][0] = green_val1; dft_image_green[k][1] = green_val2; float blue_val1 = dft_image_blue[k][0] * dft_kernel_blue[k][0] - dft_image_blue[k][1] * dft_kernel_blue[k][1]; float blue_val2 = dft_image_blue[k][0] * dft_kernel_blue[k][1] + dft_image_blue[k][1] * dft_kernel_blue[k][0]; dft_image_blue[k][0] = blue_val1; dft_image_blue[k][1] = blue_val2; } } ///Perform the inverse DFT on the multiplication result fftw_complex *idft_image_red = idft(dft_image_red, padded_input_image->getWidth(), padded_input_image->getHeight()); fftw_complex *idft_image_green = idft(dft_image_green, padded_input_image->getWidth(), padded_input_image->getHeight()); fftw_complex *idft_image_blue = idft(dft_image_blue, padded_input_image->getWidth(), padded_input_image->getHeight()); ///Convert to Image format Image *padded_output_image = copy(idft_image_red, 0, padded_input_image->getWidth(), padded_input_image->getHeight(), 0x00); copy(idft_image_green, 1, padded_input_image->getWidth(), padded_input_image->getHeight(), padded_output_image); copy(idft_image_blue, 2, padded_input_image->getWidth(), padded_input_image->getHeight(), padded_output_image); //Unpad the image Image *squared_output_image = unpadImage(padded_output_image, kernel_half_sizex, kernel_half_sizey); Image *output_image = new Image(input_image->getWidth(), input_image->getHeight()); for (int y=0;y<output_image->getHeight();y++) { for (int x=0;x<output_image->getWidth();x++) { output_image->setPixel(x,y,squared_output_image->getPixel(x,y)); } } output_image->normalize(); output_image->normalize(range); fftw_free(dft_image_red); fftw_free(dft_image_green); fftw_free(dft_image_blue); fftw_free(dft_kernel_red); fftw_free(dft_kernel_green); fftw_free(dft_kernel_blue); fftw_free(idft_image_red); fftw_free(idft_image_green); fftw_free(idft_image_blue); delete padded_input_image; delete padded_output_image; delete squared_input_image; delete squared_output_image; delete [] range; return output_image; }
OOFImage3D::OOFImage3D(const std::string &name, const std::string &format, const std::string &filepattern, int numfiles) : name_(name) { vtkImageReader2 *imageReader; vtkIndent indent; int depth = numfiles; // the width and height seem to be set automatically int extent[6] = {0,0,0,0,0,depth-1}; if(format.compare("pnm")==0 || format.compare("pbm")==0 || format.compare("ppm")==0) { imageReader = vtkPNMReader::New(); } else if(format.compare("jpeg")==0) { imageReader = vtkJPEGReader::New(); } else if(format.compare("tiff")==0) { imageReader = vtkTIFFReader::New(); } else if(format.compare("png")==0) { imageReader = vtkPNGReader::New(); } else throw ErrSetupError("Incompatible image format: " + format); //cout << "imageReader refcount " << imageReader->GetReferenceCount() << endl; //imageReader->SetReferenceCount(1); //imageReader->UnRegister((vtkObjectBase*)imageReader->GetExecutive()); //cout << "imageReader refcount " << imageReader->GetReferenceCount() << endl; imageReader->SetDataExtent(extent); imageReader->SetDataSpacing(1,1,1); imageReader->SetFilePattern( filepattern.c_str() ); imageReader->SetDataScalarTypeToUnsignedChar(); //cout << imageReader->GetReleaseDataFlag() << endl; //imageReader->ReleaseDataFlagOn(); //imageReader->DebugOn(); //cout << imageReader->GetReleaseDataFlag() << endl; //cout << "imageReader refcount " << imageReader->GetReferenceCount() << endl; image = imageReader->GetOutput(); image->Update(); pipeline.push_back(imageReader); // for certain image formats such as PNG, the bit depth may be // greater than 8 and the reader will return a vtkImageData object // with a scalar type other than unsigned char. We need to scale // the data and make it an unsigned char type if(image->GetScalarType() != VTK_UNSIGNED_CHAR) { vtkImageShiftScale *shiftscale = vtkImageShiftScale::New(); shiftscale->SetInput(image); shiftscale->SetShift(0); shiftscale->SetScale(255.0/image->GetScalarTypeMax()); shiftscale->SetOutputScalarTypeToUnsignedChar(); image = shiftscale->GetOutput(); image->Update(); pipeline.push_back(shiftscale); } //image->DebugOn(); //cout << "image refcount " << image->GetReferenceCount() << endl; //image->Register(NULL); //cout << "image refcount " << image->GetReferenceCount() << endl; //image->SetSource(NULL); //cout << "image refcount " << image->GetReferenceCount() << endl; //imageReader->Delete(); //cout << "image refcount " << image->GetReferenceCount() << endl; image = getRGBA(); padImage(1); //image->PrintSelf(cout, indent); setup(); }