0
$\begingroup$

I am at the moment trying to implement a contra harmonic filter,to remove the pepper noise from an image. But the implementation of it seems a bit incorrect, and I am not sure what is wrong.

void ContraHarmonic(Mat src, Mat dst, int kernel, double P)
{
  cout << "got it" << endl;
    Mat temp = src.clone();
    //copyMakeBorder(temp,temp,kernel-1,kernel-1,kernel-1,kernel-1,BORDER_CONSTANT,Scalar(0,0,0));

    for(int row = kernel/2; row < temp.rows - kernel/2-1; row++)
    {
        for(int col = kernel/2; col < temp.cols - kernel/2-1; col++)
        {

        double den=0,num=0;
          for(int i = -(kernel/2); i <= (kernel/2) ; i++)
          {
            for(int j = -(kernel/2) ; j <= (kernel/2); j++)
            {
                den += pow(temp.at<float>(row+i,col+j),P);
                num += pow(temp.at<float>(row+i,col+j),P+1);
            }
          }

        dst.at<float>(row,col) = num/den;
      }
    }
    dst.convertTo(dst,CV_8U);
}

The output i receive from it point at something being wrong with it.. I am not sure whether the implementation is incorrect, or the programming isn't done correctly. This is the output i receive.. Which point at something being wrong.

enter image description here

--Updated--

Updated with the answer provided and the image looks like this enter image description here

$\endgroup$
1
$\begingroup$

The problem occurred due to the pixel values of temp had the type uchar.

The solution to my problem was to output the pixel values as uchar, manipulate them as double, and store them as uchar.

double den=0,num=0;
      for(int i = -(kernel/2); i <= (kernel/2) ; i++)
      {
        for(int j = -(kernel/2) ; j <= (kernel/2); j++)
        {
            den += pow(temp.at<uchar>(row+i,col+j),P);
            num += pow(temp.at<uchar>(row+i,col+j),P+1);
        }
      }

    dst.at<uchar>(row,col) = num/den;
$\endgroup$
0
$\begingroup$

If P is large, you may be getting overflow. num and den are only declared as float, but the calculation may exceed the range of a float. Change them to double.

$\endgroup$
  • $\begingroup$ I updated the code, and i am using a kernel of 3 , and p is between 2 and 5. But the output image still seems a bit ... yeah.. $\endgroup$ – Bob Burt Nov 6 '15 at 14:04
  • $\begingroup$ A lot of segmentation fault does also occur.. $\endgroup$ – Bob Burt Nov 6 '15 at 14:07
  • $\begingroup$ Well, the output image looks somewhat better. I'm wondering whether dst.at<float> should be dst.at<double>, even though it should still have a reasonable range of values. $\endgroup$ – Peter K. Nov 6 '15 at 14:24
  • $\begingroup$ den += pow(temp.at<float>(row+i,col+j),P); should it not be den += pow(temp.at<double>(row+i,col+j),P); $\endgroup$ – Bob Burt Nov 6 '15 at 15:09
  • $\begingroup$ Yes, get rid of all use of float. No point. On most modern processors they can be slower than double. $\endgroup$ – Peter K. Nov 6 '15 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.