예제 #1
0
파일: dip3.cpp 프로젝트: hoijui/DIP
/*
Performes a convolution by multiplication in frequency domain
in		input image
kernel		filter kernel
return		output image
*/
Mat frequencyConvolution(Mat& in, Mat& kernel) {

	const int kw = kernel.cols;
	const int kh = kernel.rows;

	Mat kernelBig = Mat::zeros(in.size(), in.type());
	for (int x = 0; x < kw; ++x) {
		for (int y = 0; y < kh; ++y) {
			kernelBig.at<float>(x, y) = kernel.at<float>(x, y);
		}
	}
	Mat kernelBigShifted = circShift(kernelBig, -(kw/2), -(kh/2));

	// transform into frequency domain
	Mat freqIn = Mat(in.size(), CV_32FC2); // complex
	Mat freqKernel = Mat(kernelBigShifted.size(), CV_32FC2); // complex
	dft(in, freqIn);
	dft(kernelBigShifted, freqKernel);

	// multiply in frequency domain (-> convolute in spatial domain)
	Mat freqRes = Mat(kernelBig.size(), CV_32FC2); // complex
	mulSpectrums(freqIn, freqKernel, freqRes, 0);

	// transform back into spatial domain
	Mat res(in.size(), in.type());
	dft(freqRes, res, DFT_INVERSE | DFT_SCALE);

	return res;
}
예제 #2
0
파일: Dip3.cpp 프로젝트: kziel1/dip
/*
in       input image
kernel   filter kernel
return   output image
*/
Mat Dip3::frequencyConvolution(Mat& in, Mat& kernel){

   Mat tempA = Mat::zeros(in.rows, in.cols, CV_32FC1);
   Mat tempB = Mat::zeros(in.rows, in.cols, CV_32FC1);
   
   for (int x = 0; x < kernel.rows; x++) for (int y = 0; y < kernel.cols; y++) {
      tempB.at<float>(x, y) = kernel.at<float>(x, y);
   }
   
   tempB = circShift(tempB, -1, -1);

   dft(in, tempA, 0);
   dft(tempB, tempB, 0);
   mulSpectrums(tempA, tempB, tempB, 0);
   dft(tempB, tempA, DFT_INVERSE + DFT_SCALE);

   return tempA;
}
예제 #3
0
파일: Dip3.cpp 프로젝트: easten20/DIP
void Dip3::test_circShift(void){
   
   Mat in = Mat::zeros(3,3,CV_32FC1);
   in.at<float>(0,0) = 1;
   in.at<float>(0,1) = 2;
   in.at<float>(1,0) = 3;
   in.at<float>(1,1) = 4;
   Mat ref = Mat::zeros(3,3,CV_32FC1);
   ref.at<float>(0,0) = 4;
   ref.at<float>(0,2) = 3;
   ref.at<float>(2,0) = 2;
   ref.at<float>(2,2) = 1;
   
   if (sum((circShift(in, -1, -1) == ref)).val[0]/255 != 9){
      cout << "ERROR: Dip3::circShift(): Result of circshift seems to be wrong!" << endl;
      return;
   }
   cout << "Message: Dip3::circShift() seems to be correct" << endl;
}
예제 #4
0
파일: Dip3.cpp 프로젝트: easten20/DIP
/*
in       input image
kernel   filter kernel
return   output image
*/
Mat Dip3::frequencyConvolution(Mat& in, Mat& kernel){
     
    Mat freq_in, freq_kernel, result;
 
    //copy kernel to large matrix (the size of input image)
    cv::Rect roi(cv::Point(0,0),kernel.size());
    Mat destinationROI = Mat::zeros(in.size(), in.type());
    kernel.copyTo(destinationROI(roi));

    //perform circ shift on kernel 
    Mat circ_kernel = circShift(destinationROI, -kernel.cols/2, -kernel.rows/2);

    //convert to frequency domains
    dft(in, freq_in, 0);
    dft(circ_kernel, freq_kernel, 0);

    //multiplication in freq domains
    mulSpectrums(freq_in, freq_kernel, freq_in,0);
    
    //convert to spatial domain
    dft(freq_in, result, DFT_INVERSE + DFT_SCALE);

    return result;
}
예제 #5
0
파일: Dip4.cpp 프로젝트: kziel1/dip
/*
degraded :  degraded input image
filter   :  filter which caused degradation
return   :  restorated output image
*/
Mat Dip4::inverseFilter(Mat& degraded, Mat& filter){

  // be sure not to touch them
  degraded = degraded.clone();
  filter = filter.clone();

  Mat tempA = Mat::zeros(degraded.size(), CV_32FC1);
  
  Mat degradedFreq = degraded.clone();
  Mat filterFreq = Mat::zeros(degraded.size(), CV_32F);

  // add Border
  for (int x = 0; x < filter.rows; x++) for (int y = 0; y < filter.cols; y++) {
    filterFreq.at<float>(x, y) = filter.at<float>(x, y);
  }
   
  filterFreq = circShift(filterFreq, -1, -1);

  // transform to complex 
  Mat planes[] = {degradedFreq, Mat::zeros(degraded.size(), CV_32F)};
  Mat planesFilter[] = {filterFreq, Mat::zeros(filterFreq.size(), CV_32F)};
  
  merge(planes, 2, degradedFreq);
  merge(planesFilter, 2, filterFreq);

  // convert to frequency spectrum
  dft(degradedFreq, degradedFreq, DFT_COMPLEX_OUTPUT); // degradedFreq == S
  dft(filterFreq, filterFreq, DFT_COMPLEX_OUTPUT); // filterFreq == P

  // create Q

  split(filterFreq, planes);

  Mat Re = planes[0];
  Mat Im = planes[1];
  
  // calculate Threshold
  double thresholdFactor = 0.05, threshold;
  double max = 0;

  // find maximum
  for (int x = 0; x < filterFreq.rows; x++) for (int y = 0; y < filterFreq.cols; y++) {
    float resq = Re.at<float>(x, y) * Re.at<float>(x, y);
    float imsq = Im.at<float>(x, y) * Im.at<float>(x, y);

    float absreim = sqrt(resq + imsq);
    if (absreim > max) {
      max = absreim;
    }
  }
  
  threshold = thresholdFactor * max;

  for (int x = 0; x < filterFreq.rows; x++) for (int y = 0; y < filterFreq.cols; y++) {
    
    float resq = Re.at<float>(x, y) * Re.at<float>(x, y);
    float imsq = Im.at<float>(x, y) * Im.at<float>(x, y);

    float absreim = sqrt(resq + imsq);

    if (absreim >= threshold) {

      Re.at<float>(x, y) = Re.at<float>(x, y) / (resq + imsq);
      Im.at<float>(x, y) = Im.at<float>(x, y) / (resq + imsq);

    } else {
      Re.at<float>(x, y) = 0;
      Im.at<float>(x, y) = 0;
    }

  }
  
  Mat Q = Mat::zeros(filterFreq.size(), CV_32F);
  
  merge(planes, 2, Q);

  Mat original;

  mulSpectrums(degradedFreq, Q, original, 1);
  dft(original, original, DFT_INVERSE + DFT_SCALE);
  split(original, planes);

  original = planes[0];
  normalize(original, original, 0, 255, CV_MINMAX);
  original.convertTo(original, CV_8UC1);
 
  return original;
}