Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 模拟各向同性线性扩散平滑_Opencv_Filtering_Smoothing - Fatal编程技术网

Opencv 模拟各向同性线性扩散平滑

Opencv 模拟各向同性线性扩散平滑,opencv,filtering,smoothing,Opencv,Filtering,Smoothing,我想应用我在标题中命名的去噪过滤器,它基于以下等式: 其中,d=1是标量常数扩散系数参数,I(x,y)是初始噪声图像,u(x,y,t)是扩散时间t后获得的图像,假设5、10和30。然而,为了在OpenCV中实现这一点,我对使用哪个函数以及如何使用感到非常困惑。我觉得这很简单,但出于某种原因,我感到困惑。有人有主意吗 以下是一个示例图像: 然后,我想将其与高斯滤波方法进行比较,该方法符合以下要求: 其中G√2t(x,y)是高斯核。这证明了对t时间d=1执行各向同性线性扩散与对σ=√(2t)

我想应用我在标题中命名的去噪过滤器,它基于以下等式:

其中,
d=1
是标量常数扩散系数参数,
I(x,y)
是初始噪声图像,
u(x,y,t)
是扩散时间
t
后获得的图像,假设
5、10和30
。然而,为了在OpenCV中实现这一点,我对使用哪个函数以及如何使用感到非常困惑。我觉得这很简单,但出于某种原因,我感到困惑。有人有主意吗

以下是一个示例图像:

然后,我想将其与高斯滤波方法进行比较,该方法符合以下要求:

其中
G√2t(x,y)
是高斯核。这证明了对
t
时间
d=1
执行各向同性线性扩散与对
σ=√(2t)

我有一个应用高斯滤波的函数:

void gaussian_2D_convolution(const cv::Mat& src, cv::Mat& dst, const float sigma, const int ksize_x = 0, const int ksize_y = 0)
{
    int ksize_x_ = ksize_x, ksize_y_ = ksize_y;

    // Compute an appropriate kernel size according to the specified sigma
    if (sigma > ksize_x || sigma > ksize_y || ksize_x == 0 || ksize_y == 0)
    {
        ksize_x_ = (int)ceil(2.0f*(1.0f + (sigma - 0.8f) / (0.3f)));
        ksize_y_ = ksize_x_;
    }

    // The kernel size must be and odd number
    if ((ksize_x_ % 2) == 0)
    {
        ksize_x_ += 1;
    }

    if ((ksize_y_ % 2) == 0)
    {
        ksize_y_ += 1;
    }

    // Perform the Gaussian Smoothing
    GaussianBlur(src, dst, Size(ksize_x_, ksize_y_), sigma, sigma, BORDER_DEFAULT);

    // show result
    std::ostringstream out;
    out << std::setprecision(1) << std::fixed << sigma;
    String title = "sigma: " + out.str();
    imshow(title, dst);
    imwrite("gaussian/" + title + ".png", dst);

    waitKey(260);
}
void gaussian_2D_卷积(常数cv::Mat&src,cv::Mat&dst,常数float sigma,常数int ksize_x=0,常数int ksize_y=0)
{
int ksize_x_uu=ksize_x,ksize_y_uu=ksize_y;
//根据指定的sigma计算适当的内核大小
如果(sigma>ksize|x | sigma>ksize|y | ksize|x==0 | | ksize|y==0)
{
ksize_x_=(int)ceil(2.0f*(1.0f+(sigma-0.8f)/(0.3f));
ksize_y_uu=ksize_x_uu;
}
//内核大小必须为1和奇数
如果((ksize_x_u%2)==0)
{
ksize_x_u+=1;
}
如果((ksize_y_%2)==0)
{
ksize_y_+=1;
}
//执行高斯平滑
GaussianBlur(src、dst、Size(ksize_x_、ksize_y_)、sigma、sigma、BORDER_默认值);
//显示结果
std::ostringstream out;

out这应该按预期工作。这是基于:

  • 关于你的问题的评论
代码:

#包括
使用名称空间cv;
空隙ILD(常数Mat1b和src、Mat1b和dst、int iter=10、双扩散系数=1.0、双λ=0.1)
{
Mat1f-img;
src.convertTo(仪表组,CV_32F);
lambda=fmax(0.001,std::fmin(lambda,0.25));//默认情况下[0,0.25]中的某些内容应该是0.25
而(国际热核实验堆--)
{
Mat1f圈;
拉普拉斯(img、lap、CV_32F);
img+=λ*扩散系数*搭接;
}
img.convertTo(dst,CV_8U);
}
int main(){
Mat1b img=imread(“路径到图像”,imread\U灰度);
Mat1b res_ilds;
国际标准(img、res_-ilds);
imshow(“ILDS”,res_ILDS);
waitKey();
返回0;
}
结果:


让我知道它是否适合你

Hi@Miki谢谢你的回答和你的时间。我一回到我的工作站就会尝试。但是有一个问题,因为你的方法基于Perona-Malik方法,所以它不是模拟等距线性平滑,而是各向异性非线性,对吗?@theodore它是isotropic!P&M:
I+=lambda*(g(dN)。*dN+g(dS)。*dS+g(dE)。*dE+g(dW)。*dW)
,其中
dN
是图像在北向的空间导数,依此类推。函数g确定扩散行为。如果
g(x)=1
(类似于本例)这是标准的各向同性扩散。好的,我看到运行你的代码可以像你说的那样工作。但是,我想验证一些事情。据我所知,
g
函数对应于扩散系数参数
d
对吗?如果是,那么你的代码可以更正确地转换为
img+=lambda*d*lap;
其中
 d
是1。此外,
iter
变量表示扩散时间
t
参数,对吗?但是,如果我对
iter
使用值5,则应对应于
σ=√(2t)=3.2
用于高斯平滑,两者应给出相同的结果,但它们没有。此外,在我的初始公式中,没有提到任何
lambda
变量,因此如何将其添加到计算中。最后,您使用拉普拉斯滤波器以获得导数,我可以使用sobel或scharr滤波器用于ge吗修正导数,这会改变什么,或者我将使用哪种方法来获得它并不重要。@theodore
img+=lambda*d*lap
正确。
iter
正确。如果我使用……实际上不知道。
lambda
在P&M公式中,你可以将其修正为默认值0.25。你需要拉普拉斯算子,你可以合作和索贝尔一起计算,但我看不出有什么好的理由。让我知道
#include <opencv2\opencv.hpp>
using namespace cv;

void ilds(const Mat1b& src, Mat1b& dst, int iter = 10, double diffusivity = 1.0, double lambda = 0.1)
{
    Mat1f img;
    src.convertTo(img, CV_32F);
    lambda = fmax(0.001, std::fmin(lambda, 0.25)); // something in [0, 0.25] by default should be 0.25
    while (iter--)
    {
        Mat1f lap;
        Laplacian(img, lap, CV_32F);
        img += lambda * diffusivity * lap;
    }

    img.convertTo(dst, CV_8U);
}

int main() {

    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
    Mat1b res_ilds;
    ilds(img, res_ilds);

    imshow("ILDS", res_ilds);
    waitKey();

    return 0;
}