VTK 边缘检测_Sobel算子

1.Sobel算子用于提取图像边缘

Sobel算子也是一种常用的梯度算子。Sobel算子计算稍微复杂,它采用3x3的模板。计算时模板在图像上移动,并在每个位置上计算对应中心像素的梯度值。
VTK中vtkSobel2D计算图像的sobel算子,使用代码如下:
  1 #include <vtkAutoInit.h>
  2 VTK_MODULE_INIT(vtkRenderingOpenGL);
  3  
  4 #include <vtkSmartPointer.h>
  5 #include <vtkJPEGReader.h>
  6 #include <vtkImageSobel2D.h>
  7 #include <vtkImageExtractComponents.h>
  8 #include <vtkImageMathematics.h>
  9 #include <vtkImageData.h>
 10 #include <vtkImageShiftScale.h>
 11 #include <vtkImageActor.h>
 12 #include <vtkRenderer.h>
 13 #include <vtkRenderWindow.h>
 14 #include <vtkRenderWindowInteractor.h>
 15 #include <vtkInteractorStyleImage.h>
 16  
 17 int main()
 18 {
 19     vtkSmartPointer<vtkJPEGReader> reader =
 20         vtkSmartPointer<vtkJPEGReader>::New();
 21     reader->SetFileName("lena.jpg");
 22     reader->Update();
 23  
 24     vtkSmartPointer<vtkImageSobel2D> sobelFilter =
 25         vtkSmartPointer<vtkImageSobel2D>::New();
 26     sobelFilter->SetInputConnection(reader->GetOutputPort());//包含横向和竖向边缘
 27  
 28     //提取X向边缘成分
 29     vtkSmartPointer<vtkImageExtractComponents> xSobel =
 30         vtkSmartPointer<vtkImageExtractComponents>::New();
 31     xSobel->SetComponents(0);//提取第一成分即X向梯度
 32     xSobel->SetInputConnection(sobelFilter->GetOutputPort());
 33     xSobel->Update();
 34  
 35     vtkSmartPointer<vtkImageMathematics> absFilter =
 36         vtkSmartPointer<vtkImageMathematics>::New();
 37     absFilter->SetOperationToAbsoluteValue();//将属性设置为绝对值模式
 38     absFilter->SetInputConnection(xSobel->GetOutputPort());
 39     absFilter->Update();
 40  
 41     double xRange[2];
 42     absFilter->GetOutput()->GetScalarRange(xRange);
 43  
 44     vtkSmartPointer<vtkImageShiftScale> xShiftScale =
 45         vtkSmartPointer<vtkImageShiftScale>::New();
 46     xShiftScale->SetOutputScalarTypeToUnsignedChar();//强制类型转换 方便显示
 47     xShiftScale->SetScale(255 / xRange[1]);//设置属性
 48     xShiftScale->SetInputConnection(absFilter->GetOutputPort());
 49     xShiftScale->Update();
 50     
 51     //提取Y向边缘成分
 52     vtkSmartPointer<vtkImageExtractComponents> ySobel =
 53         vtkSmartPointer<vtkImageExtractComponents>::New();
 54     ySobel->SetComponents(1);
 55     ySobel->SetInputConnection(sobelFilter->GetOutputPort());
 56     ySobel->Update();
 57  
 58     vtkSmartPointer<vtkImageMathematics> absYsobel =
 59         vtkSmartPointer<vtkImageMathematics>::New();
 60     absYsobel->SetOperationToAbsoluteValue();
 61     absYsobel->SetInputConnection(ySobel->GetOutputPort());
 62     absYsobel->Update();
 63  
 64     double yRange[2];
 65     absYsobel->GetOutput()->GetScalarRange(yRange);
 66  
 67     vtkSmartPointer<vtkImageShiftScale> yShiftScale =
 68         vtkSmartPointer<vtkImageShiftScale>::New();
 69     yShiftScale->SetOutputScalarTypeToUnsignedChar();
 70     yShiftScale->SetScale(255 / yRange[1]);
 71     yShiftScale->SetInputConnection(absYsobel->GetOutputPort());
 72     yShiftScale->Update();
 73     
 74     vtkSmartPointer<vtkImageActor> origActor =
 75         vtkSmartPointer<vtkImageActor>::New();
 76     origActor->SetInputData(reader->GetOutput());
 77  
 78     vtkSmartPointer<vtkImageActor> xSobelActor =
 79         vtkSmartPointer<vtkImageActor>::New();
 80     xSobelActor->SetInputData(xShiftScale->GetOutput());
 81  
 82     vtkSmartPointer<vtkImageActor> ySobelActor =
 83         vtkSmartPointer<vtkImageActor>::New();
 84     ySobelActor->SetInputData(yShiftScale->GetOutput());
 85     /
 86     double origView[4] = { 0, 0, 0.33, 1 };
 87     double xSobelView[4] = { 0.33, 0, 0.66, 1 };
 88     double ySobelView[4] = { 0.66, 0, 1, 1 };
 89     vtkSmartPointer<vtkRenderer> origRender =
 90         vtkSmartPointer<vtkRenderer>::New();
 91     origRender->SetViewport(origView);
 92     origRender->AddActor(origActor);
 93     origRender->ResetCamera();
 94     origRender->SetBackground(1, 0, 0);
 95  
 96     vtkSmartPointer<vtkRenderer> xSobelRender =
 97         vtkSmartPointer<vtkRenderer>::New();
 98     xSobelRender->SetViewport(xSobelView);
 99     xSobelRender->AddActor(xSobelActor);
100     xSobelRender->ResetCamera();
101     xSobelRender->SetBackground(0, 1, 0);
102  
103     vtkSmartPointer<vtkRenderer> ySobelRender =
104         vtkSmartPointer<vtkRenderer>::New();
105     ySobelRender->SetViewport(ySobelView);
106     ySobelRender->AddActor(ySobelActor);
107     ySobelRender->ResetCamera();
108     ySobelRender->SetBackground(0, 0, 1);
109     //
110     vtkSmartPointer<vtkRenderWindow> rw =
111         vtkSmartPointer<vtkRenderWindow>::New();
112     rw->AddRenderer(origRender);
113     rw->AddRenderer(xSobelRender);
114     rw->AddRenderer(ySobelRender);
115     rw->SetSize(960, 320);
116     rw->SetWindowName("Edge by Soebl");
117  
118     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
119         vtkSmartPointer<vtkRenderWindowInteractor>::New();
120     vtkSmartPointer<vtkInteractorStyleImage> style =
121         vtkSmartPointer<vtkInteractorStyleImage>::New();
122     rwi->SetInteractorStyle(style);
123     rwi->SetRenderWindow(rw);
124     rwi->Initialize();
125     rwi->Start();
126  
127     return 0;
128 }
该例中计算利用Sobel算子计算图像的梯度图像,然后提取X方向的梯度分量和Y方向的梯度分量。
由于计算Sobel算子的值可能存在负值,因此利用vtkImageMathematics对各个分量图像计算绝对值,再由vtkImageShiftScale将图像的数值范围调节到0-255之间再显示。
执行结果如下:
原文地址:https://www.cnblogs.com/ybqjymy/p/14241419.html