https://github.com/PetteriAimonen/focus-stack
https://github.com/Biomedical-Imaging-Group/EDF-Extended-Depth-of-Field
Helicon Focus 软件 3d重建效果

focus-stack 输出的融合图像

focus-stack 输出的3d渲染图像

仅修改Task_FocusMeasure 后的3d渲染图像

soebel 改laplacian
cpp
void Task_FocusMeasure::task()
{
// Algorithm is based on Tenengrad focus measure from
// 'Autofocusing Algorithm Selection in Computer Microscopy' by Sun et Al.
const cv::Mat &input = m_input->img();
int rows = input.rows;
int cols = input.cols;
m_valid_area = m_input->valid_area();
// Calculate squared gradient magnitude by calculating
// horizontal and vertical Sobel operator.
cv::Mat sobel(rows, cols, CV_32F);
cv::Mat magnitude(rows, cols, CV_32F, cv::Scalar(0));
cv::Sobel(input, sobel, CV_32FC1, 1, 0);
cv::accumulateSquare(sobel, magnitude);
cv::Sobel(input, sobel, CV_32FC1, 0, 1);
cv::accumulateSquare(sobel, magnitude);
sobel.release();
//cv::Mat laplacian;
//cv::Laplacian(input, laplacian, CV_32F);
//cv::Mat magnitude(rows, cols, CV_32F, cv::Scalar(0));
//cv::multiply(laplacian, laplacian, magnitude); // squared Laplacian = variance proxy
//cv::Mat temp;
//cv::GaussianBlur(magnitude, temp, cv::Size(), 1, 1, cv::BORDER_REFLECT);
////cv::bilateralFilter(magnitude, temp, 5, 500, 5);
//cv::medianBlur(temp, temp, 3);
//magnitude = std::move(temp);
m_input.reset();
magnitude.setTo(0, magnitude < m_threshold);
if (m_radius > 0)
{
int blurwindow = (int)(m_radius * 4) + 1;
cv::GaussianBlur(magnitude, magnitude, cv::Size(blurwindow, blurwindow), m_radius, m_radius, cv::BORDER_REFLECT);
}
cv::sqrt(magnitude, m_result);
}