OpenCV denoising a 3x3 pixel pattern noise

This picture

shows two photos captured by a camera from a black photographic paper. The cross is marked by laser. The left one shows a 9 pixel pattern of noise.

This gets in the way of auto-focus process.

Backgroud： My boss asked me to improve the auto-focus algorithm of a camera to a higher precision (say from 1mm to 0.01mm). This auto-focus process is a preparation stage for laser marking.

The original algorithm uses "Sobel" to calculate sharpness and compare the sharpness of photos at consecutive camera distance to see which one corresponds to the distance nearest to focal length.

Sobel(im_gray, grad_x);convertScaleAbs(grad_x, abs_grad_x);
for (int i = 0; i < grad.rows; i++)
for (int j = 0; j < grad.cols; j++)
sharpness += = grad.at<unsigned char>(i, j);


This algorithm works fine for complicated photo (with higher brightness and more info), despite the noise, the sharpness value changes monotonically. But for simple photo (with less brightness and less info), the sharpness value doesn't change monotonically.

I first noticed brightness variance gets in the way of calculating the correct sharpness so I used histogram equalization (already tried "BrightnessAndContrastAuto", not working), and it improves the result to some extent.

equalizeHist(im_gray, im_gray);


After inspecting the problematic shapness values, I realized the noise is another interfering factor. So I used GaussianBlur both of size 3x3 and 5x5 to denoise (already tried "fastNlMeansDenoising", not working ) before histogram equalization. Still there are problematic sharpness values ( certain values break the monotonic trend).

GaussianBlur(im_gray, im_gray, Size(5, 5), 0);
result:
-0.2    41.5362
-0.18   41.73
-0.16   41.9194
-0.14   42.2535
-0.12   42.4438
-0.1    42.9528
-0.08   **42.6879**
-0.06   43.4243
-0.04   43.7608
-0.02   43.9139
0       44.1061
0.02    44.3472
0.04    44.7846
0.06    44.9305
0.08    45.0761
0.1     **44.8107**
0.12    45.1979
0.14    45.7114
0.16    45.9627
0.18    46.2388
0.2     46.6344


To sum up,my current algorithm is as follows:

GaussianBlur(im_gray, im_gray, Size(5, 5), 0);
equalizeHist(im_gray, im_gray);