Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

You can't get back information you lost due to pixel saturation. All you can do is to try some synthetic reconstruction using information from neighbour like cv::inpaint function does. Just to show, below is a simple code that use uses cv::inpaint.

//helper function
void Morphology(const Mat &imgIn,Mat &imgOut,int morpOp=MORPH_CLOSE,
                           int minThickess=2,int shape=MORPH_ELLIPSE)
{
  int size = minThickess / 2;
  Point anchor = Point(size, size);
  Mat element = getStructuringElement(shape, Size(2 * size + 1, 2 * size + 1), anchor);
  morphologyEx(imgIn, imgOut, morpOp, element, anchor);
}
void Main_Inpaint()
{
  Mat src,blur,mask,bkMask,fgMask,dst;
  vector<vector<Point> > contours;
  src = imread("pixel-saturation1.png");
  // remove noise
  cv::GaussianBlur(src,blur,Size(),2,2);
  //CREATE A MASK FOR THE SATURATED PIXEL
  int minBrightness=253;
  int dilateSize=20;
  //convert to HSV
  Mat src_hsv,brightness,saturation;
  vector<Mat> hsv_planes;
  cvtColor(blur, src_hsv, COLOR_BGR2HSV);
  split(src_hsv, hsv_planes);
  brightness = hsv_planes[2];
  //get the mask
  threshold(brightness,mask,minBrightness,255,THRESH_BINARY);
  //dialte a bit the selection
  Morphology(mask,mask,MORPH_DILATE,dilateSize);
  //INPAINTING
  float radius=5.0;
  inpaint(src,mask,dst,radius,INPAINT_NS);
  imshow("Navier-Stokes based method",dst);

  inpaint(src,mask,dst,radius,INPAINT_TELEA);
  imshow("Method by Alexandru Telea ",dst);
  //show the selection on src
  findContours(mask, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
  for (int i = 0; i < contours.size(); i++)
    drawContours(src,contours,i,Scalar(0,0,255),2);
  imshow("Inpaint mask",src);
  waitKey(0);
}

The result is pretty nice with 1st image but fails with your 2nd case.

image description

I know it's a completely total different approach, but if you can control camera/acquisition, you could try to reduce the brightness/gain/shutter down to remove spotlight...

It would be easier to recover dark region if a bit of information will survive see Automated Removal of Partial Occlusion Blur for reference.

Another option is High Dynamic Range...

click to hide/show revision 2
No.2 Revision

You can't get back information you lost due to pixel saturation. All you can do is to try some synthetic reconstruction using information from neighbour like cv::inpaint function does. Just to show, below is a simple code that use uses cv::inpaint.

//helper function
void Morphology(const Mat &imgIn,Mat &imgOut,int morpOp=MORPH_CLOSE,
                           int minThickess=2,int shape=MORPH_ELLIPSE)
{
  int size = minThickess / 2;
  Point anchor = Point(size, size);
  Mat element = getStructuringElement(shape, Size(2 * size + 1, 2 * size + 1), anchor);
  morphologyEx(imgIn, imgOut, morpOp, element, anchor);
}
void Main_Inpaint()
{
  Mat src,blur,mask,bkMask,fgMask,dst;
  vector<vector<Point> > contours;
  src = imread("pixel-saturation1.png");
  // remove noise
  cv::GaussianBlur(src,blur,Size(),2,2);
  //CREATE A MASK FOR THE SATURATED PIXEL
  int minBrightness=253;
  int dilateSize=20;
  //convert to HSV
  Mat src_hsv,brightness,saturation;
  vector<Mat> hsv_planes;
  cvtColor(blur, src_hsv, COLOR_BGR2HSV);
  split(src_hsv, hsv_planes);
  brightness = hsv_planes[2];
  //get the mask
  threshold(brightness,mask,minBrightness,255,THRESH_BINARY);
  //dialte a bit the selection
  Morphology(mask,mask,MORPH_DILATE,dilateSize);
  //INPAINTING
  float radius=5.0;
  inpaint(src,mask,dst,radius,INPAINT_NS);
  imshow("Navier-Stokes based method",dst);

  inpaint(src,mask,dst,radius,INPAINT_TELEA);
  imshow("Method by Alexandru Telea ",dst);
  //show the selection on src
  findContours(mask, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
  for (int i = 0; i < contours.size(); i++)
    drawContours(src,contours,i,Scalar(0,0,255),2);
  imshow("Inpaint mask",src);
  waitKey(0);
}

The result is pretty nice with 1st image but fails with your 2nd case.

image description

I know it's a completely total different approach, but if you can control camera/acquisition, you could try to reduce the brightness/gain/shutter down to remove spotlight...

It would be easier to recover dark region if a bit of information will survive see Automated Removal of Partial Occlusion Blur for reference.

Another option is High Dynamic Range...