zoukankan      html  css  js  c++  java
  • VTK 边缘检测_梯度算子

    1.梯度算子提取图像边缘

    图像中不连续的灰度值会产生边缘,图像的边缘检测是基于边界的图像分割方法,如分水岭算法,通常是分割原图的梯度图像,梯度实际上也是反应的图像边缘信息。图像边缘一般常用图像一阶导数和二阶导数来检测。
    梯度算子对应于图像一阶导数。图像一阶导数计算一般是通过差分运算来近似的。VTK中可以使用vtkImageGradient计算图像梯度。注意图像梯度是一个向量,具有方向和大小。因此vtkImageGradient的计算结果是一个梯度场,也就是每个像素值都是一个梯度向量。显示梯度图像时需要计算每个像素点的梯度大小,即模值。
    下面代码如何利用VTK怎么计算图像梯度:
     1 #include <vtkAutoInit.h>
     2 VTK_MODULE_INIT(vtkRenderingOpenGL);
     3  
     4 #include <vtkSmartPointer.h>
     5 #include <vtkJPEGReader.h>
     6 #include <vtkImageGradient.h>
     7 #include <vtkImageMagnitude.h>
     8 #include <vtkImageData.h>
     9 #include <vtkImageShiftScale.h>
    10 #include <vtkImageActor.h>
    11 #include <vtkRenderer.h>
    12 #include <vtkRenderWindow.h>
    13 #include <vtkRenderWindowInteractor.h>
    14 #include <vtkInteractorStyleImage.h>
    15  
    16 int main()
    17 {
    18     vtkSmartPointer<vtkJPEGReader> reader =
    19         vtkSmartPointer<vtkJPEGReader>::New();
    20     reader->SetFileName("lena.jpg");
    21     reader->Update();
    22  
    23     vtkSmartPointer<vtkImageGradient> imgGradient =
    24         vtkSmartPointer<vtkImageGradient>::New();
    25     imgGradient->SetInputConnection(reader->GetOutputPort());
    26     imgGradient->SetDimensionality(2);//?????
    27  
    28     vtkSmartPointer<vtkImageMagnitude> imgMagnitude =
    29         vtkSmartPointer<vtkImageMagnitude>::New();
    30     imgMagnitude->SetInputConnection(imgGradient->GetOutputPort());
    31     imgMagnitude->Update();
    32  
    33     double Range[2];
    34     vtkSmartPointer<vtkImageData> getRange =
    35         vtkSmartPointer<vtkImageData>::New();
    36     imgMagnitude->GetOutput()->GetScalarRange(Range);//图像灰度范围最小值、最大值
    37  
    38     vtkSmartPointer<vtkImageShiftScale> imgShiftScale =
    39         vtkSmartPointer<vtkImageShiftScale>::New();
    40     imgShiftScale->SetOutputScalarTypeToUnsignedChar(); //强制类型转换 0~255
    41     imgShiftScale->SetScale(255 / Range[1]); //灰度映射间距
    42     imgShiftScale->SetInputConnection(imgMagnitude->GetOutputPort());
    43     imgShiftScale->Update();
    44  
    45     /
    46     vtkSmartPointer<vtkImageActor> origActor =
    47         vtkSmartPointer<vtkImageActor>::New();
    48     origActor->SetInputData(reader->GetOutput());
    49  
    50     vtkSmartPointer<vtkImageActor> GradientActor =
    51         vtkSmartPointer<vtkImageActor>::New();
    52     GradientActor->SetInputData(imgShiftScale->GetOutput());
    53     
    54     double origView[4] = { 0, 0, 0.5, 1 };
    55     double gradientView[4] = { 0.5, 0, 1, 1 };
    56     vtkSmartPointer<vtkRenderer> origRender =
    57         vtkSmartPointer<vtkRenderer>::New();
    58     origRender->SetViewport(origView);
    59     origRender->AddActor(origActor);
    60     origRender->ResetCamera();
    61     origRender->SetBackground(1.0, 0, 0);
    62  
    63     vtkSmartPointer<vtkRenderer> gradientRender =
    64         vtkSmartPointer<vtkRenderer>::New();
    65     gradientRender->SetViewport(gradientView);
    66     gradientRender->AddActor(GradientActor);
    67     gradientRender->ResetCamera();
    68     gradientRender->SetBackground(1, 1, 1);
    69     
    70     vtkSmartPointer<vtkRenderWindow> rw =
    71         vtkSmartPointer<vtkRenderWindow>::New();
    72     rw->AddRenderer(origRender);
    73     rw->AddRenderer(gradientRender);
    74     rw->SetSize(640, 320);
    75     rw->SetWindowName("Image Gradient");
    76  
    77     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
    78         vtkSmartPointer<vtkRenderWindowInteractor>::New();
    79     vtkSmartPointer<vtkInteractorStyleImage> style =
    80         vtkSmartPointer<vtkInteractorStyleImage>::New();
    81     rwi->SetRenderWindow(rw);
    82     rwi->SetInteractorStyle(style);
    83     rwi->Initialize();
    84     rwi->Start();
    85  
    86     return 0;
    87 }
    vtkImageGradient的使用比较简单,只需要设置输入图像即可。
    计算梯度时,采用的是中间差分法,即像素在每个方向的差分,都是利用的前后两个像素值之差。这样在图像在边界处的差分计算需要特殊处理。其内部定义了HandleBoundaries变量,通过函数SetHandleBoundaries()定赋值。当HandleBoundaries为真时算子会特殊处理计算边界像素的梯度;当为假时不计算边界像素的梯度值,因此输出图像大小要小于输入图像。
    另外函数SetDimensionality()用于设置要计算的图像维数,默认为二维,此时梯度向量也为二维。
    前面也提到过,梯度是一个向量,不能直接显示。
    因此上面代码中定义了vtkImageMagnitude对象来计算梯度向量的2范数,即向量的模。
    利用vtkImageShiftScale将图像的数据范围调整到0-255然后显示。
    另外还可以通过vtkImageExtractComponents来提取每个方向的梯度分量进行显示。
    注意,彩色图像不能直接用来计算梯度,需要先转换为灰度图像。
    本例的执行结果如下图所示。
  • 相关阅读:
    kali渗透综合靶机(十七)--HackInOS靶机
    kali渗透综合靶机(十六)--evilscience靶机
    kali渗透综合靶机(十五)--Breach-1.0靶机
    kali渗透综合靶机(十四)--g0rmint靶机
    DVWA-文件上传学习笔记
    kali渗透综合靶机(十三)--Dina 1.0靶机
    Weblogic-SSRF漏洞复现
    kali渗透综合靶机(十二)--SickOs1.2靶机
    IIS_CVE-2015-1635-HTTP.SYS远程执行代码漏洞复现
    【Flask+Redis】 python学习第一章
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14241408.html
Copyright © 2011-2022 走看看