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

news2024/12/26 5:21:50

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),显示为红色。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在跨平台开发环境中构建高效的C++项目:从基础到最佳实践20241225

在跨平台开发环境中构建高效的C项目:从基础到最佳实践 引言 在现代软件开发中,跨平台兼容性和高效开发流程是每个工程师追求的目标。尤其是对于 C 开发者,管理代码的跨平台构建以及调试流程可能成为一项棘手的挑战。在本文中,我…

网络协议入门

一、概述 1、模型 为了减少协议设计的复杂性,大多数网络模型均采用分层的方式来组织。每一层都有自己的功能,就像建筑物一样,每一层都靠下一层支持。每一层利用下一层提供的服务来为上一层提供服务,本层服务的实现细节对上层屏蔽…

集成RabbitMQ+MQ常用操作

文章目录 1.环境搭建1.Docker安装RabbitMQ1.拉取镜像2.安装命令3.开启5672和15672端口4.登录控制台 2.整合Spring AMQP1.sun-common模块下创建新模块2.引入amqp依赖和fastjson 3.新建一个mq-demo的模块1.在sun-frame下创建mq-demo2.然后在mq-demo下创建生产者和消费者子模块3.查…

sentinel笔记10- 限流规则持久化(下)

上一篇整理过单向的持久化,sentinel笔记9- 限流规则持久化(上)-CSDN博客 本篇进行sentinel 改造,实现双向同步。 1 下载Sentinel源码 https://github.com/alibaba/Sentinel 2 dashboard 改造 2.1修改dashboard项目的pom.xml &…

微服务篇-深入了解 XXL-JOB 分布式任务调度的具体使用(XXL-JOB 的工作流程、框架搭建)

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 XXL-JOB 调度中心概述 1.2 XXL-JOB 工作流程 1.3 Cron 表达式调度 2.0 XXL-JOB 框架搭建 2.1 XXL-JOB 调度中心的搭建 2.2 XXL-JOB 执行器的搭建 2.3 使用调度中心…

【jenkins插件】

1) 2) 3) 4) 5) 6) 参考: 知识库/运维/Jenkins/01-安装/13-插件.md zfoo/java-developer-document - 码云 - 开源中国

孔雀鱼和斑马鱼能一起养吗?

在观赏鱼的世界里,孔雀鱼和斑马鱼都是备受鱼友喜爱的热门品种。它们独特的外形和相对容易的饲养条件,使得不少养鱼新手跃跃欲试将它们混养在一起,但这其中实则有诸多因素需要考量。 从生存环境来看,孔雀鱼和斑马鱼有一定的兼容性…

踏踏实实练SQLday1

踏踏实实练SQLday1 1连续登录1.1查询连续登录3天以上的用户第一步去重第二步-开窗rownumber,用date减一下,对结果进行分组 -- over()开窗函数知识图谱第三步 1.2查询连续登录最大天数用户1.3某个用户连续登录天数注意先where一下这个用户的数据过滤出来.…

UM-Net:基于不确定性建模的息肉分割方法,对ICGNet的重新思考|文献速递-生成式模型与transformer在医学影像中的应用

Title 题目 UM-Net: Rethinking ICGNet for polyp segmentation with uncertainty modeling UM-Net:基于不确定性建模的息肉分割方法,对ICGNet的重新思考 01 文献速递介绍 结直肠癌(CRC)是男性中第三大最常见的恶性肿瘤&…

C语言项目 天天酷跑(上篇)

前言 这里讲述这个天天酷跑是怎么实现的,我会在天天酷跑的下篇添加源代码,这里会讲述天天酷跑这个项目是如何实现的每一个思路,都是作者自己学习于别人的代码而创作的项目和思路,这个代码和网上有些许不一样,因为掺杂了…

协众OA checkLoginQrCode接口 SQL注入漏洞

FOFA app"协众软件-协众OA" 漏洞复现 nuclei运行结果

如何用gpt来分析链接里面的内容(比如分析论文链接)和分析包含多个文件中的一块代码

如何用gpt来分析链接里面的内容,方法如下 这里使用gpt4里面有一个网路的功能 点击搜索框下面这个地球的形状即可启动搜索网页模式 然后即可提出问题在搜索框里:发现正确识别和分析了链接里面的内容 链接如下:https://arxiv.org/pdf/2009.1…

jdk各个版本介绍

JDK(Java Development Kit)是Java开发者用于构建、测试和部署Java应用程序的工具包。随着Java语言的不断演进,JDK也经历了多个版本的更新。下面是对JDK各个主要版本的简要介绍: JDK 1.0 - 1.4(经典时代) •…

OpenCV(python)从入门到精通——运算操作

加法减法操作 import cv2 as cv import numpy as npx np.uint8([250]) y np.uint8([10])x_1 np.uint8([10]) y_1 np.uint8([20])# 加法,相加最大只能为255 print(cv.add(x,y))# 减法,相互减最小值只能为0 print(cv.subtract(x_1,y_1))图像加法 import cv2 as…

大湾区经济网报道 | 第三届湾商大会暨湾区未来产业发展论坛隆重举行

大湾区经济网12月25日电(首席记者 余芳),在中国式现代化进程与世界新机遇交汇的大背景下,要精准定位并奋力攀登未来科技与产业发展的高峰,加速推进新一代信息技术、人工智能、量子科技、生物科技、新能源以及新材料等领…

CV-OCR经典论文解读|An Empirical Study of Scaling Law for OCR/OCR 缩放定律的实证研究

论文标题 An Empirical Study of Scaling Law for OCR OCR 缩放定律的实证研究 论文链接: An Empirical Study of Scaling Law for OCR论文下载 论文作者 Miao Rang, Zhenni Bi, Chuanjian Liu, Yunhe Wang, Kai Han 内容简介 本论文在光学字符识别&#xf…

ES已死,文本检索永生

长期以来,混合查询(Hybrid Search)一直是提升 RAG(Retrieval-Augmented Generation)搜索质量的重要手段。尽管基于密集向量(Dense Embedding)的搜索技术随着模型规模和预训练数据集的不断扩展&a…

K线单边突破指标(附带源码)

编写需求: 今天我们来根据粉丝要求进行源码复现: 【请根据最近两根K线判断当下的行情做多,做空方向。用三个价格判断当前K线状态,最高价、最低价、收盘价都大于昨日对应价格,为上涨K线。用三个价格判断当前K线状态&a…

基于Springboot的在线问卷调查系统【附源码】

基于Springboot的在线问卷调查系统 效果如下: 系统主页面 问卷列表页面 个人中心页面 系统登陆页面 管理员主页面 问卷管理页面 研究背景 随着互联网技术的飞速发展,传统的问卷调查方式因其时间和地点的限制,难以高效地收集到足够的数据。…

SpringBoot状态机

Spring Boot 状态机(State Machine)是 Spring Framework 提供的一种用于实现复杂业务逻辑的状态管理工具。它基于有限状态机(Finite State Machine, FSM)的概念,允许开发者定义一组状态、事件以及它们之间的转换规则。…