VTK图像处理 边缘检测 梯度算子

图像中不连续的灰度值会产生边缘,图像的边缘检测是基于边界的图像分割方法的基础。分水岭算法通常是分割原图的梯度图像,而梯度实际上也反映图像的边缘信息

梯度算子对应于图像的一阶导数。图像的一阶导数一般是通过差分运算来近似的。VTK中可以用vtkImageCradient类计算图像梯度。

梯度是矢量,不能直接显示。使用vtkImageMagnitude对象来计算梯度矢量的2-范数,既矢量的模。利用vtkImageShiftScale将图像的数据范围调整到「0 255」然后显示。注意:彩色图像不能直接用来计算梯度,需要先转换为灰度图像。

#define HH 0
#ifndef  HH
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);

#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageSobel2D.h>
#include <vtkImageExtractComponents.h>
#include <vtkImageMathematics.h>
#include <vtkImageData.h>
#include <vtkImageShiftScale.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>


int main()
{
	vtkSmartPointer<vtkJPEGReader> reader =
		vtkSmartPointer<vtkJPEGReader>::New();
	reader->SetFileName("C:/Users/Administrator/Pictures/1.jpg");
	reader->Update();

	vtkSmartPointer<vtkImageSobel2D> sobelFilter =
		vtkSmartPointer<vtkImageSobel2D>::New();
	sobelFilter->SetInputConnection(reader->GetOutputPort());//包含横向和竖向边缘

	//提取X向边缘成分
	vtkSmartPointer<vtkImageExtractComponents> xSobel =
		vtkSmartPointer<vtkImageExtractComponents>::New();
	xSobel->SetComponents(0);//提取第一成分即X向梯度
	xSobel->SetInputConnection(sobelFilter->GetOutputPort());
	xSobel->Update();

	vtkSmartPointer<vtkImageMathematics> absFilter =
		vtkSmartPointer<vtkImageMathematics>::New();
	absFilter->SetOperationToAbsoluteValue();//将属性设置为绝对值模式
	absFilter->SetInputConnection(xSobel->GetOutputPort());
	absFilter->Update();

	double xRange[2];
	absFilter->GetOutput()->GetScalarRange(xRange);

	vtkSmartPointer<vtkImageShiftScale> xShiftScale =
		vtkSmartPointer<vtkImageShiftScale>::New();
	xShiftScale->SetOutputScalarTypeToUnsignedChar();//强制类型转换 方便显示
	xShiftScale->SetScale(255 / xRange[1]);//设置属性
	xShiftScale->SetInputConnection(absFilter->GetOutputPort());
	xShiftScale->Update();

	//提取Y向边缘成分
	vtkSmartPointer<vtkImageExtractComponents> ySobel =
		vtkSmartPointer<vtkImageExtractComponents>::New();
	ySobel->SetComponents(1);
	ySobel->SetInputConnection(sobelFilter->GetOutputPort());
	ySobel->Update();

	vtkSmartPointer<vtkImageMathematics> absYsobel =
		vtkSmartPointer<vtkImageMathematics>::New();
	absYsobel->SetOperationToAbsoluteValue();
	absYsobel->SetInputConnection(ySobel->GetOutputPort());
	absYsobel->Update();

	double yRange[2];
	absYsobel->GetOutput()->GetScalarRange(yRange);

	vtkSmartPointer<vtkImageShiftScale> yShiftScale =
		vtkSmartPointer<vtkImageShiftScale>::New();
	yShiftScale->SetOutputScalarTypeToUnsignedChar();
	yShiftScale->SetScale(255 / yRange[1]);
	yShiftScale->SetInputConnection(absYsobel->GetOutputPort());
	yShiftScale->Update();

	vtkSmartPointer<vtkImageActor> origActor =
		vtkSmartPointer<vtkImageActor>::New();
	origActor->SetInputData(reader->GetOutput());

	vtkSmartPointer<vtkImageActor> xSobelActor =
		vtkSmartPointer<vtkImageActor>::New();
	xSobelActor->SetInputData(xShiftScale->GetOutput());

	vtkSmartPointer<vtkImageActor> ySobelActor =
		vtkSmartPointer<vtkImageActor>::New();
	ySobelActor->SetInputData(yShiftScale->GetOutput());
 
	 
	 double origView[4] = { 0, 0, 0.33, 1 };
	double xSobelView[4] = { 0.33, 0, 0.66, 1 };
	double ySobelView[4] = { 0.66, 0, 1, 1 };
	vtkSmartPointer<vtkRenderer> origRender =
		vtkSmartPointer<vtkRenderer>::New();
	origRender->SetViewport(origView);
	origRender->AddActor(origActor);
	origRender->ResetCamera();
	origRender->SetBackground(1, 0, 0);

	vtkSmartPointer<vtkRenderer> xSobelRender =
		vtkSmartPointer<vtkRenderer>::New();
	xSobelRender->SetViewport(xSobelView);
	xSobelRender->AddActor(xSobelActor);

	xSobelRender->ResetCamera();
	xSobelRender->SetBackground(0, 1, 0);

	vtkSmartPointer<vtkRenderer> ySobelRender =
		vtkSmartPointer<vtkRenderer>::New();
	ySobelRender->SetViewport(ySobelView);
	ySobelRender->AddActor(ySobelActor);
	ySobelRender->ResetCamera();
	ySobelRender->SetBackground(0, 0, 1);
	//
	vtkSmartPointer<vtkRenderWindow> rw =
		vtkSmartPointer<vtkRenderWindow>::New();
	rw->AddRenderer(origRender);
	rw->AddRenderer(xSobelRender);
	rw->AddRenderer(ySobelRender);
	rw->SetSize(960, 320);
	rw->SetWindowName("Edge by Soebl");

	vtkSmartPointer<vtkRenderWindowInteractor> rwi =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	vtkSmartPointer<vtkInteractorStyleImage> style =
		vtkSmartPointer<vtkInteractorStyleImage>::New();
	rwi->SetInteractorStyle(style);
	rwi->SetRenderWindow(rw);
	rwi->Initialize();
	rwi->Start();

	return 0;
}

#else 

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL)
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkStructuredPoints.h>
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPNGReader.h>
#include <vtkImageLuminance.h>
#include <vtkProperty.h>
#include <vtkImageGaussianSmooth.h>
#include <vtkImageCast.h>
#include <vtkImageGradient.h>
#include <vtkImageMagnitude.h>
#include <vtkImageNonMaximumSuppression.h>
#include <vtkImageConstantPad.h>
#include <vtkImageToStructuredPoints.h>
#include <vtkLinkEdgels.h>
#include <vtkThreshold.h>
#include <vtkGeometryFilter.h>
#include <vtkSubPixelPositionEdgels.h>
#include <vtkStripper.h>
#include <vtkPolyDataMapper.h>
#include <vtkCamera.h>
#include <vtkJPEGReader.h>
#include <vtkInteractorStyleImage.h>
#include <vtkImageShiftScale.h>


int main(int argc, char* argv[])
{
 
 
	vtkSmartPointer<vtkJPEGReader> reader =
		vtkSmartPointer<vtkJPEGReader>::New();
	reader->SetFileName("C:/Users/Administrator/Pictures/1.jpg");
	reader->Update();

	vtkSmartPointer<vtkImageLuminance> luminanceFilter =
		vtkSmartPointer<vtkImageLuminance>::New();
	luminanceFilter->SetInputConnection(reader->GetOutputPort());
	luminanceFilter->Update();

	 

	vtkSmartPointer<vtkImageGradient> gradientFilter =
		vtkSmartPointer<vtkImageGradient>::New();
	gradientFilter->SetInputConnection(luminanceFilter->GetOutputPort());
	gradientFilter->SetDimensionality(2);

	vtkSmartPointer<vtkImageMagnitude> magnitudeFilter =
		vtkSmartPointer<vtkImageMagnitude>::New();
	magnitudeFilter->SetInputConnection(gradientFilter->GetOutputPort());
	magnitudeFilter->Update();

	double range[2];
	magnitudeFilter->GetOutput()->GetScalarRange(range);

	vtkSmartPointer<vtkImageShiftScale> ShiftScale =
		vtkSmartPointer<vtkImageShiftScale>::New();
	ShiftScale->SetOutputScalarTypeToUnsignedChar();
	ShiftScale->SetScale(255 / range[1]);
	ShiftScale->SetInputConnection(magnitudeFilter->GetOutputPort());
	ShiftScale->Update();

 

	vtkSmartPointer<vtkImageActor> gradActor =
		vtkSmartPointer<vtkImageActor>::New();
	gradActor->SetInputData(ShiftScale->GetOutput());

	double originalViewport[4] = { 0.0, 0.0, 0.5, 1.0 };
	double gradviewport[4] = { 0.5, 0.0, 1.0, 1.0 };

 

	vtkSmartPointer<vtkRenderer> gradRenderer =
		vtkSmartPointer<vtkRenderer>::New();
	gradRenderer->SetViewport(gradviewport);
	gradRenderer->AddActor(gradActor);
	gradRenderer->ResetCamera();
	gradRenderer->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
 
	renderWindow->AddRenderer(gradRenderer);
	renderWindow->SetSize(640, 320);
	renderWindow->Render();
	renderWindow->SetWindowName("ImageGradientExample");

	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	vtkSmartPointer<vtkInteractorStyleImage> style =
		vtkSmartPointer<vtkInteractorStyleImage>::New();

	renderWindowInteractor->SetInteractorStyle(style);
	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderWindowInteractor->Initialize();
	renderWindowInteractor->Start();

	return EXIT_SUCCESS;

 
}
#endif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恋恋西风

up up up

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值