VTK知识学习(27)- 图像基本操作(二)

1、图像类型转换

1)vtkImageCast

        图像数据类型转换在数字图像处理中会频繁用到。一些常用的图像算子(例如梯度算子)在计算时出于精度的考虑,会将结果存储为float或double类型,但在图像显示时,一般要求图像为 unsigned char 类型,这时就需要对数据类型进行转换。VTK 中最简单的类型转换 Filter就是 vtkmageCast,其使用方法如下:

vtkImageCast imageCast = vtkImageCast.New();
imageCast.SetInputConnection(reader.GetOutputPort());
imageCast.SetOutputScalarTypeToFloat();
imageCast.Update();

        只需要把 SetOutputScalarTypeToxxX()设置成相应的输出类型即可。另外,该类中还有一个变量 ClampOverflow,用来标识是否需要截断数据。默认情况下,该变量值为0。当设置其值为1时,输出的像素值不能超过输出类型的最大值,超过时自动截断至最大值。该类在进行类型转换时,只是将数据进行强制转换,而没有进行比例的缩放,因此使用比较受限制,VTK中也不推荐使用该类。例如一幅 double 类型的图像,其数值范围为[-1,1],如果需要将图像转换为 unsigned char 类,则无法使用该 Filter 进行转换。这时就需要用到 vklmageShifScale。

2)vtkImageShiftScale

       指定偏移和比例参数来对输入图像数据进行操作,例如一幅double 类型的图像,其数值范围为[-1,1],如果将其转换为 unsigned char 类型,需要设置 shif值为+1,比例系数设置为 127.5,那么输入数据-1映射为(-1+1)x127.5=0,而+1 则会映射为(+1+1)x127.5=255。对应代码如下:

vtkImageShiftScale imageShiftScale = vtkImageShiftScale.New();
imageShiftScale.SetInputConnection(reader.GetOutputPort());
 imageShiftScale.SetOutputScalarTypeToUnsignedChar();
imageShiftScale.SetShift(1);
imageShiftScale.SetScale(127.5);
imageShiftScale.Update();

         SetShift()函数,用于设置偏移量 Shift

        SetScale()函数,用于设置放缩值Scale,如果源图像的像素值为Val,那么输出值为(Val+shif)xScale。

        SetOutputScalarTypeToUnsignedChar()用于设置输出类型为 unsigned char,当然,该类也提供了其他输出类型的设置函数。

        该类中也有一个变量ClampOverfow,当其值为1时,如果输出值超过输出类型的最大值时,则自动截断。例如,输出类型为 unsigned char,数值范围为 0~255,当输出像素值为 257时,该类会自动截断取值为 255。默认情况下,变量 ClampOverflow 的值为 0,此时,当输出值为 257,输出类型为 unsigned char 时,该类不会将其截断,而是会产生溢出,最后取值为2。

2、图像颜色映射

1)图像灰度映射

        vtkImageLuminance 负责将一个RGB 彩色图像转换为一个单组分的灰度图像。映射公
式为:
        Luminance=0.3xR+0.59xG+0.11xB
         R为输入图像的第一组分(红色),G为第二组分(绿色),B为第三组分(蓝色)。

        这个公式用于计算一个RGB颜色的亮度。该类的使用也比较简单,用户无须设置参数。

private void TestColor2Gray()
{
    vtkBMPReader reader = vtkBMPReader.New();
    reader.SetFileName("F:\\code\\VTK\\TestActiViz\\bin\\Debug\\data\\lena.bmp");
    reader.Update();

    vtkImageLuminance luminance = vtkImageLuminance.New();
    luminance.SetInputData(reader.GetOutput());
    luminance.Update();

    vtkImageActor orgActor = vtkImageActor.New();
    orgActor.SetInputData(reader.GetOutput());

    vtkImageActor actor = vtkImageActor.New();
    actor.SetInputData(luminance.GetOutput());

    vtkRenderer orgRenderer = vtkRenderer.New();
    orgRenderer.AddActor(orgActor);
    orgRenderer.SetViewport(0.0, 0.0, 0.5, 1.0);
    orgRenderer.ResetCamera();
    orgRenderer.SetBackground(1, 1, 1);

    vtkRenderer renderer = vtkRenderer.New();
    renderer.SetViewport(0.5, 0.0, 1.0, 1.0);
    renderer.AddActor(actor);

    renderer.ResetCamera();
    renderer.SetBackground(1, 1, 1);

    vtkRenderWindow renderWindow = renderWindowControl.RenderWindow;
    renderWindow.AddRenderer(orgRenderer);
    renderWindow.AddRenderer(renderer);
    renderWindow.Render();
}

2)提取颜色组分

        VTK 中利用 vtkImageExtractComponents 可以方便地提取彩色图像的各个颜色组分。使用该类时只需要设置要提取的组分序号即可。

private void TestExtractComponets()
 {
   vtkBMPReader reader = vtkBMPReader.New();
   reader.SetFileName("F:\\code\\VTK\\TestActiViz\\bin\\Debug\\data\\lena.bmp");
   reader.Update();

   //提取红色对应灰度图像
   vtkImageExtractComponents extractRed = vtkImageExtractComponents.New();
   extractRed.SetInputData(reader.GetOutput());
   extractRed.SetComponents(0);
   extractRed.Update();

   //提取绿色对应灰度图像
   vtkImageExtractComponents extractGreen = vtkImageExtractComponents.New();
   extractGreen.SetInputData(reader.GetOutput());
   extractGreen.SetComponents(1);
   extractGreen.Update();

   //提取蓝色对应灰度图像
   vtkImageExtractComponents extractBlue = vtkImageExtractComponents.New();
   extractBlue.SetInputData(reader.GetOutput());
   extractBlue.SetComponents(2);
   extractBlue.Update();

   vtkImageActor orgActor = vtkImageActor.New();
   orgActor.SetInputData(reader.GetOutput());

   vtkImageActor redActor = vtkImageActor.New();
   redActor.SetInputData(extractRed.GetOutput());

   vtkImageActor greenActor = vtkImageActor.New();
   greenActor.SetInputData(extractGreen.GetOutput());

   vtkImageActor blueActor = vtkImageActor.New();
   blueActor.SetInputData(extractBlue.GetOutput());

   vtkRenderer orgRenderer = vtkRenderer.New();
   orgRenderer.AddActor(orgActor);
   orgRenderer.SetViewport(0.0, 0.0, 0.25, 1.0);
   orgRenderer.ResetCamera();
   orgRenderer.SetBackground(1, 1, 1);

   vtkRenderer renderer = vtkRenderer.New();
   renderer.SetViewport(0.25, 0.0, 0.5, 1.0);
   renderer.AddActor(redActor);
   renderer.ResetCamera();
   renderer.SetBackground(1, 1, 1);

   vtkRenderer renderer2 = vtkRenderer.New();
   renderer2.SetViewport(0.5, 0.0, 0.75, 1.0);
   renderer2.AddActor(greenActor);
   renderer2.ResetCamera();
   renderer2.SetBackground(1, 1, 1);

   vtkRenderer renderer3 = vtkRenderer.New();
   renderer3.SetViewport(0.75, 0.0, 1, 1.0);
   renderer3.AddActor(blueActor);
   renderer3.ResetCamera();
   renderer3.SetBackground(1, 1, 1);

   vtkRenderWindow renderWindow = renderWindowControl.RenderWindow;
   renderWindow.AddRenderer(orgRenderer);
   renderWindow.AddRenderer(renderer);
   renderWindow.AddRenderer(renderer2);
   renderWindow.AddRenderer(renderer3);
   renderWindow.Render();
}

        代码中定义了三个 vtkImageExtractComponents 对象,分别用来提取红、绿和蓝色组分图像,函数 SetComponents()用来设置要提取的组分号,红、绿、蓝三色分别对应0、1和2。设置完毕,执行Update()即可得到各个组分的数据。其输出为vtkImageData,每一个颜色组分数据即是一个灰度图像。

3)图像彩色映射

        图像彩色映射的原理是:先生成一个颜色查找表,然后根据图像像素的一个标量值在颜色查找表中查找对应的颜色,并用新颜色值替代原来的像素值。VTK中以vkImageMapToColors 实现图像彩色映射,以 vkookUpTable 生成颜色查找表。

   

private void TestGray2Color()
        {
            vtkJPEGReader reader = vtkJPEGReader.New();
            reader.SetFileName("F:\\code\\VTK\\TestActiViz\\bin\\Debug\\data\\lena-gray.jpg");
            reader.Update();

            vtkLookupTable colorTable = vtkLookupTable.New();
            colorTable.SetRange(0, 255);
            colorTable.SetHueRange(0.1, 0.5);
            colorTable.SetValueRange(0.6, 1);
            colorTable.Build();

            vtkImageMapToColors colorMap = vtkImageMapToColors.New();
            colorMap.SetInputData(reader.GetOutput());
            colorMap.SetLookupTable(colorTable);
            colorMap.Update();

            vtkImageActor orgActor = vtkImageActor.New();
            orgActor.SetInputData(reader.GetOutput());

            vtkImageActor redActor = vtkImageActor.New();
            redActor.SetInputData(colorMap.GetOutput());

            vtkRenderer orgRenderer = vtkRenderer.New();
            orgRenderer.AddActor(orgActor);
            orgRenderer.SetViewport(0.0, 0.0, 0.5, 1.0);
            orgRenderer.ResetCamera();
            orgRenderer.SetBackground(1, 1, 1);

            vtkRenderer renderer = vtkRenderer.New();
            renderer.SetViewport(0.5, 0.0, 1, 1.0);
            renderer.AddActor(redActor);
            renderer.ResetCamera();
            renderer.SetBackground(1, 1, 0.8);

            vtkRenderWindow renderWindow = renderWindowControl.RenderWindow;
            renderWindow.AddRenderer(orgRenderer);
            renderWindow.AddRenderer(renderer);

            renderWindow.Render();
        }

        示例先读取了一幅灰度图像,然后生成 vtkLookUpTable 颜色查找表。

        构造颜色查找表有两种方法:一种是直接添加颜色;另一种是设置HSV颜色空间变化范围,然后自动生成颜色表。这里采用的是第二种方法,

SetRange()设置要映射的标量数据的范围:

SetHueRange()设置HSV 颜色空间的 Hue 值范围,最大范围为[0,1];

SetValueRange()设置 HSV 颜色空间的 Value 范围,最大范围为[0,1]:

设置完后,调用 Build()来生成颜色査找表。接着定义 vkImageMapToColors 对象,vtkImageMapToColors::SetLookupTable()设置相应的颜色查找表,执行 Update()后,其输出为一幅彩色图像。 

4)颜色合成

        VTK也支持将多个灰度图像合并成一个彩色图像。VTK 中的 vtkImageAppendComponents 类可用来合成彩色图像,其输入需要提供三个灰度图像。

private void TestColorAppend()
        {
            vtkImageCanvasSource2D red = vtkImageCanvasSource2D.New();
            red.SetScalarTypeToUnsignedChar();
            red.SetNumberOfScalarComponents(1);
            red.SetExtent(0, 100, 0, 100, 0, 0);
            red.SetDrawColor(0, 0, 0, 0);
            red.FillBox(0, 100, 0, 100);
            red.SetDrawColor(255, 0, 0, 0);
            red.FillBox(20, 40, 20, 40);
            red.Update();

            vtkImageCanvasSource2D green = vtkImageCanvasSource2D.New();
            green.SetScalarTypeToUnsignedChar();
            green.SetNumberOfScalarComponents(1);
            green.SetExtent(0, 100, 0, 100, 0, 0);
            green.SetDrawColor(0, 0, 0, 0);
            green.FillBox(0, 100, 0, 100);
            green.SetDrawColor(255, 0, 0, 0);
            green.FillBox(30, 50, 30, 50);
            green.Update();

            vtkImageCanvasSource2D blue = vtkImageCanvasSource2D.New();
            blue.SetScalarTypeToUnsignedChar();
            blue.SetNumberOfScalarComponents(1);
            blue.SetExtent(0, 100, 0, 100, 0, 0);
            blue.SetDrawColor(0, 0, 0, 0);
            blue.FillBox(0, 100, 0, 100);
            blue.SetDrawColor(255, 0, 0, 0);
            blue.FillBox(40, 60, 40, 60);
            blue.Update();

            vtkImageAppendComponents components = vtkImageAppendComponents.New();
            components.SetInputData(0, red.GetOutput());
            components.AddInputData(0, green.GetOutput());
            components.AddInputData(0, blue.GetOutput());
            components.Update();

            vtkImageActor redActor = vtkImageActor.New();
            redActor.SetInputData(red.GetOutput());

            vtkImageActor greenActor = vtkImageActor.New();
            greenActor.SetInputData(green.GetOutput());

            vtkImageActor blueActor = vtkImageActor.New();
            blueActor.SetInputData(blue.GetOutput());

            vtkImageActor combinedActor = vtkImageActor.New();
            combinedActor.SetInputData(components.GetOutput());

            vtkRenderer redRenderer = vtkRenderer.New();
            redRenderer.AddActor(redActor);
            redRenderer.SetViewport(0.0, 0.0, 0.25, 1.0);
            redRenderer.ResetCamera();
            redRenderer.SetBackground(1, 1, 1);

            vtkRenderer greenRenderer = vtkRenderer.New();
            greenRenderer.AddActor(greenActor);
            greenRenderer.SetViewport(0.25, 0.0, 0.5, 1.0);
            greenRenderer.ResetCamera();
            greenRenderer.SetBackground(1, 1, 1);

            vtkRenderer blueRenderer = vtkRenderer.New();
            blueRenderer.AddActor(blueActor);
            blueRenderer.SetViewport(0.5, 0.0, 0.75, 1.0);
            blueRenderer.ResetCamera();
            blueRenderer.SetBackground(1, 1, 1);

            vtkRenderer CombinedRenderer = vtkRenderer.New();
            CombinedRenderer.SetViewport(0.75, 0.0, 1, 1.0);
            CombinedRenderer.AddActor(combinedActor);
            CombinedRenderer.ResetCamera();
            CombinedRenderer.SetBackground(1, 1, 0.8);

            vtkRenderWindow renderWindow = renderWindowControl.RenderWindow;
            renderWindow.AddRenderer(redRenderer);
            renderWindow.AddRenderer(greenRenderer);
            renderWindow.AddRenderer(blueRenderer);
            renderWindow.AddRenderer(CombinedRenderer);

            renderWindow.Render();
        }

        先利用 vtkImageCanvasSource2D定义了三个二值图像,每个图像中绘制了一个白色矩形,并且三个矩形有部分重叠;然后定义vkImageAppendComponents对象,并将三个图像设置为 vtkImageAppendComponents 对象的输入来合成图像。合成的效果为三个图像中对应的三个像素点的像素值合成一个RGB 像素值,如三个图像中第100个像素的像素值分别为255、0和 0,那么该点在输出图像中的像素值为(255.0.0),显示为红色。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/942386.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Go C编程 第6课 无人机 --- 计算旋转角

旋转的秘密---认识角度 rt、lt命令学习 goc电子课程 一、编程步骤 第一步 第二步 第三步 第四步 二、画“四轴无人机” (一)、画第一根机轴 (二)、画第二根机轴 (三)、画完整的无人机 三、画“多轴无人…

cursor保存更改操作技巧

1. 当我们在agent模式时,要求cursor更改代码时,cursor回答后,就已经更改了代码了,这时候就可以对程序进行编译和测试, 不一定先要点” accept“, 先测试如果没有问题再点“accept”,这样composer就会多一条…

graphRAG+llama3.2的MOOC课程资源问答系统

文章目录 参考代码地址anacondapycharmLLaMA 3传统ragGraphRAG初始化提示词微调 prompt tuning来创建更适应知识库的知识图谱使用语言模型(LLM)从每个文本块中提取实体、关系和声明。检索 query(本地搜索(Local Search&#xff09…

一键打断线(根据相交点打断)——CAD c# 二次开发

多条相交线根据交点一键打断,如下图: 部分代码如下: finally namespace IFoxDemo; public class Class1 {[CommandMethod("ddx")]public static void Demo(){//"ifox可以了".Print();Database db HostApplicationServices.Workin…

Websocket客户端从Openai Realtime api Sever只收到部分数据问题分析

目录 背景 分析 解决方案 背景 正常情况下,会从Openai Realtime api Sever收到正常的json数据,但是当返回音频数据时,总会返回非json数据。这是什么问题呢? 分析 期望的完整响应数据如下: {"session": {"inp…

flask后端开发(1):第一个Flask项目

目录 一、Helloworddebug、host、port的配置 一、Helloword 一般是会创建两个文件夹和app.py app.py from flask import FlaskappFlask(__name__)app.route(/) def hello_world():return Hello World!if __name__ __main__:app.run()右键运行这个py文件,消息绑定…

OAuth 2.0

简介 OAuth 是一种开放标准的授权协议或框架,它提供了一种安全的方式,使第三方应用程序能够访问用户在其他服务上的受保护资源,而无需共享用户的凭证(如用户名和密码)。OAuth 的核心思想是通过“授权令牌”来代替直接…

玩原神学编程-原神时钟

前言 最近喜欢玩原神这种开放世界探索的游戏(还有黑神话、古墓丽影等),只能说纳塔版本的boss盾真的厚,萌新的我去打boss,从白天打到黑夜,黑夜再打到白天(游戏里面的时间)。 闲话结…

【Spring】深入解析 Spring 原理:Bean 的多方面剖析(源码阅读)

🔥个人主页: 中草药 🔥专栏:【Java】登神长阶 史诗般的Java成神之路 一、Bean的作用域 在 Java Spring 框架中,Bean 的作用域是一个关键概念,它决定了 Bean 的生命周期和实例化方式,对应用的性…

基于高德地图js api实现掩膜效果 中间矢量 周围卫星图

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>管网服务</title><style>html,body,#ma…

Vue.js组件(6):echarts组件

1 前言 本章主要对常用的echars图表展示进行基本的组件封装。使用该组件前需要在项目中引入echarts。官网&#xff1a;Apache ECharts npm install echarts --save 2 图表组件 2.1 折线图组件 组件属性&#xff1a;chartId&#xff0c;指定图表挂载div的id&#xff0c;注意不…

RCE常见姿势

文章目录 常见漏洞执行函数&#xff1a;1.系统命令执行函数2.代码执行函数 命令拼接符读取文件命令绕过&#xff1a;空格过滤绕过关键字绕过长度过滤绕过无参数命令执行绕过无字母数字绕过利用%0A截断利用回溯绕过利用create_function()代码注入无回显RCE1.反弹shell2.dnslog外…

selenium执行js

JS知识 获取元素 document.getElement 移除属性&#xff1a;removeAttribute("xx") 窗口移动&#xff1a;window.scrollTo(0, document.body.scrollHeight)方法 drivier.execute_script(js)场景&#xff1a; 日期选择框&#xff0c;不能输入&#xff0c;只能设置…

三维场景重建与3D高斯点渲染技术探讨

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月25日10点11分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 文章源地址(有视频)&#xff1a;链接h…

springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失

这个包丢失了 启动不了 起因是pom中加入了 <tomcat.version></tomcat.version>版本指定&#xff0c;然后idea自动编译后&#xff0c;包丢了&#xff0c;删除这个配置后再也找不回来&#xff0c; 这个包正常在 <dependency><groupId>org.springframe…

Java日志框架:log4j、log4j2、logback

文章目录 配置文件相关1. properties测试 2. XMl使用Dom4j解析XML Log4j与Log4j2日志门面 一、Log4j1.1 Logges1.2 Appenders1.3 Layouts1.4 使用1.5 配置文件详解1.5.1 配置根目录1.5.2 配置日志信息输出目的地Appender1.5.3 输出格式设置 二、Log4j22.1 XML配置文件解析2.2 使…

基于LSTM长短期记忆神经网络的多分类预测【MATLAB】

在深度学习中&#xff0c;长短期记忆网络&#xff08;LSTM, Long Short-Term Memory&#xff09;是一种强大的循环神经网络&#xff08;RNN&#xff09;变体&#xff0c;专门为解决序列数据中的长距离依赖问题而设计。LSTM因其强大的记忆能力&#xff0c;广泛应用于自然语言处理…

机器学习基础 衡量模型性能指标

目录 1 前言 ​编辑1.1 错误率(Error rate)&精度(Accuracy)&误差(Error)&#xff1a; 1.2 过拟合(overfitting): 训练误差小&#xff0c;测试误差大 1.3 欠拟合(underfitting)&#xff1a;训练误差大&#xff0c;测试误差大 1.4 MSE: 1.5 RMSE: 1.6 MAE: 1.7 R-S…

TCP的流量控制的实现

滑动窗口的介绍 滑动窗口是tcp协议中的一个重要概念&#xff0c;滑动窗口是字节为单位&#xff0c;而tcp头部的序列化和确认号也是以字节为单位的&#xff0c;滑动窗口里是含有可以传输的字节的数量&#xff08;可以传输不是已经传输&#xff09;&#xff0c;而滑动窗口的大小是…

【0x001D】HCI_Read_Remote_Version_Information命令详解

目录 一、命令概述 二、命令格式及参数说明 2.12. HCI_Read_Remote_Version_Information 命令格式 2.2. Connection_Handle 三、生成事件 3.1. HCI_Command_Status 事件 3.2. HCI_Read_Remote_Version_Information_Complete 事件 四、命令执行流程 4.1. 命令发起阶段(…