VTK的渲染原理

下面三张图均是用VTK实现的,从中很容易看出它们渲染的效果是有区别的:

第一张图:过于明亮,看不到阴影,颜色过渡也不平缓;

第二张图:阴影过于明显,图整体不够明亮;

第三张图:明亮适中同时保留了阴影。

VTK是如何实现不同效果的渲染的?我们又能通过什么方式去控制渲染效果?

VTK如何实现渲染?

了解OpenGL的都知道,一个模型想要在三维视图中显示出来并控制显示效果,至少需要顶点着色器和片段着色器,VTK的底层就是用OpenGL在进行渲染,所以它也少不了这两个着色器。那么,要知道VTK如何实现渲染,实际上是要知道着色器在VTK内部是如何工作的。

着色器在VTK内部的工作流程主要包括以下几步:

  • 创建着色器
  • 生成着色器代码
  • 设置着色器参数

在说明着色器的工作流程之前,需要先了解VTK的工作机制,这样才能知道着色器每个流程具体在哪里实现的。

一个模型(以球为例)要在VTK中显示出来,至少需要创建一下几个对象:

  • vtkRenderWindow——窗口
  • vtkRenderer——渲染器,控制对象渲染过程
  • vtkSphereSource——球模型
  • vtkPolyDataMapper——将模型数据映射为几何图元
  • vtkActor——表示渲染场景中的实体

绘制接口调用顺序(以windows为例)如下:

vtkRenderWindow::Render() -> vtkRenderer::Render() -> vtkOpenGLRenderer::DeviceRender() -> vtkActor::Render() -> vtkOpenGLActor::Render() -> vtkPolyDataMapper::Render() -> vtkOpenGLPolyDataMapper::RenderPieceDraw()

着色器基本是在vtkOpenGLPolyDataMapper类中进行工作,流程包括以下几步:

1. 创建着色器

void vtkOpenGLPolyDataMapper::UpdateShaders(vtkOpenGLHelper& cellBO, vtkRenderer* ren, vtkActor* actor)
{...// build the shader source codestd::map<vtkShader::Type, vtkShader*> shaders;vtkShader* vss = vtkShader::New();vss->SetType(vtkShader::Vertex);shaders[vtkShader::Vertex] = vss;vtkShader* gss = vtkShader::New();gss->SetType(vtkShader::Geometry);shaders[vtkShader::Geometry] = gss;vtkShader* fss = vtkShader::New();fss->SetType(vtkShader::Fragment);shaders[vtkShader::Fragment] = fss;this->BuildShaders(shaders, ren, actor);...}

从上面的代码可以看到总共创建了三种着色器:顶点着色器,几何着色器和片段着色器。

2. 生成着色器代码

void vtkOpenGLPolyDataMapper::BuildShaders(std::map<vtkShader::Type, vtkShader*> shaders, vtkRenderer* ren, vtkActor* actor)
{
...this->ReplaceShaderValues(shaders, ren, actor);
...
}
void vtkOpenGLPolyDataMapper::ReplaceShaderValues(std::map<vtkShader::Type, vtkShader*> shaders, vtkRenderer* ren, vtkActor* actor)
{this->ReplaceShaderRenderPass(shaders, ren, actor, true);this->ReplaceShaderCustomUniforms(shaders, actor);this->ReplaceShaderColor(shaders, ren, actor);this->ReplaceShaderEdges(shaders, ren, actor);this->ReplaceShaderNormal(shaders, ren, actor);this->ReplaceShaderLight(shaders, ren, actor);this->ReplaceShaderTCoord(shaders, ren, actor);this->ReplaceShaderPicking(shaders, ren, actor);this->ReplaceShaderClip(shaders, ren, actor);this->ReplaceShaderPrimID(shaders, ren, actor);this->ReplaceShaderPositionVC(shaders, ren, actor);this->ReplaceShaderCoincidentOffset(shaders, ren, actor);this->ReplaceShaderDepth(shaders, ren, actor);this->ReplaceShaderRenderPass(shaders, ren, actor, false);// cout << "VS: " << shaders[vtkShader::Vertex]->GetSource() << endl;// cout << "GS: " << shaders[vtkShader::Geometry]->GetSource() << endl;// cout << "FS: " << shaders[vtkShader::Fragment]->GetSource() << endl;
}

下面的顶点着色器和片段着色器代码是完成ReplaceShaderValues()之后的生成的。

注:如需知道下面着色器代码是如何生成的,可以详细看ReplaceShaderxxx()中的流程。下面顶点着色器和片段着色器代码对应的是最上面三张图。

顶点着色器代码:

//VTK::System::Dec/*=========================================================================Program:   Visualization ToolkitModule:    vtkPolyDataVS.glslCopyright (c) Ken Martin, Will Schroeder, Bill LorensenAll rights reserved.See Copyright.txt or http://www.kitware.com/Copyright.htm for details.This software is distributed WITHOUT ANY WARRANTY; without eventhe implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULARPURPOSE.  See the above copyright notice for more information.=========================================================================*/in vec4 vertexMC;// frag position in VC
out vec4 vertexVCVSOutput;// optional normal declaration
//VTK::Normal::Dec
in vec3 normalMC;
uniform mat3 normalMatrix;
out vec3 normalVCVSOutput;// extra lighting parameters
//VTK::Light::Dec// Texture coordinates
//VTK::TCoord::Dec// material property values
in vec4 scalarColor;
out vec4 vertexColorVSOutput;// clipping plane vars
//VTK::Clip::Dec// camera and actor matrix values
uniform mat4 MCDCMatrix;
uniform mat4 MCVCMatrix;// Apple Bug
//VTK::PrimID::Dec// Value raster
//VTK::ValuePass::Dec// picking support
//VTK::Picking::Decvoid main()
{//VTK::CustomBegin::ImplvertexColorVSOutput = scalarColor;normalVCVSOutput = normalMatrix * normalMC;
//VTK::Normal::Impl//VTK::TCoord::Impl//VTK::Clip::Impl//VTK::PrimID::ImplvertexVCVSOutput = MCVCMatrix * vertexMC;gl_Position = MCDCMatrix * vertexMC;//VTK::ValuePass::Impl//VTK::Light::Impl//VTK::Picking::Impl//VTK::CustomEnd::Impl
}

vertexColorVSOutput = scalarColor; 说明顶点着色器输出的颜色是每个点对应的标量的颜色。

片段着色器代码:

//VTK::System::Dec/*=========================================================================Program:   Visualization ToolkitModule:    vtkPolyDataFS.glslCopyright (c) Ken Martin, Will Schroeder, Bill LorensenAll rights reserved.See Copyright.txt or http://www.kitware.com/Copyright.htm for details.This software is distributed WITHOUT ANY WARRANTY; without eventhe implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULARPURPOSE.  See the above copyright notice for more information.=========================================================================*/
// Template for the polydata mappers fragment shaderuniform int PrimitiveIDOffset;// VC position of this fragment
in vec4 vertexVCVSOutput;// Camera prop
uniform int cameraParallel;// optional color passed in from the vertex shader, vertexColor
uniform float ambientIntensity; // the material ambient
uniform float diffuseIntensity; // the material diffuse
uniform float opacityUniform; // the fragment opacity
uniform vec3 ambientColorUniform; // ambient color
uniform vec3 diffuseColorUniform; // diffuse color
uniform float specularIntensity; // the material specular intensity
uniform vec3 specularColorUniform; // intensity weighted color
uniform float specularPowerUniform;
in vec4 vertexColorVSOutput;// optional surface normal declaration
//VTK::Normal::Dec
uniform mat3 normalMatrix;
in vec3 normalVCVSOutput;// extra lighting parameters
uniform vec3 lightColor0;// Texture maps
//VTK::TMap::Dec// Texture coordinates
//VTK::TCoord::Dec// picking support
//VTK::Picking::Dec// Depth Peeling Support
//VTK::DepthPeeling::Dec// clipping plane vars
//VTK::Clip::Dec// the output of this shader
//VTK::Output::Dec// Apple Bug
//VTK::PrimID::Dec// handle coincident offsets
//VTK::Coincident::Dec// Value raster
//VTK::ValuePass::Dec// surface with edges
//VTK::Edges::Decvoid main()
{// VC position of this fragment. This should not branch/return/discard.vec4 vertexVC = vertexVCVSOutput;// Place any calls that require uniform flow (e.g. dFdx) here.//VTK::UniformFlow::Impl// Set gl_FragDepth here (gl_FragCoord.z by default)//VTK::Depth::Impl// Early depth peeling abort://VTK::DepthPeeling::PreColor// Apple Bug//VTK::PrimID::Impl//VTK::Clip::Impl//VTK::ValuePass::Implvec3 specularColor = specularIntensity * specularColorUniform;float specularPower = specularPowerUniform;vec3 ambientColor = ambientIntensity * vertexColorVSOutput.rgb;vec3 diffuseColor = diffuseIntensity * vertexColorVSOutput.rgb;float opacity = opacityUniform * vertexColorVSOutput.a;//VTK::Edges::Impl// Generate the normal if we are not passed in onevec3 normalVCVSOutput = normalize(normalVCVSOutput);if (gl_FrontFacing == false) { normalVCVSOutput = -normalVCVSOutput; }//VTK::Normal::Implfloat df = max(0.000001, normalVCVSOutput.z);float sf = pow(df, specularPower);vec3 diffuse = df * diffuseColor * lightColor0;vec3 specular = sf * specularColor * lightColor0;gl_FragData[0] = vec4(ambientColor + diffuse + specular, opacity);//VTK::Light::Impl//VTK::TCoord::Implif(gl_FragData[0].a <= 0.0){discard;}//VTK::DepthPeeling::Impl//VTK::Picking::Impl// handle coincident offsets//VTK::Coincident::Impl
}

3. 设置着色器参数

在第2步的片段着色器代码中,我们能看到很多输入变量,这些变量是在哪里设置呢?

void vtkOpenGLPolyDataMapper::SetPropertyShaderParameters(vtkOpenGLHelper& cellBO, vtkRenderer*, vtkActor* actor)
{
...program->SetUniformf("opacityUniform", opacity);program->SetUniformf("ambientIntensity", aIntensity);program->SetUniformf("diffuseIntensity", dIntensity);
...// handle specularif (this->PrimitiveInfo[this->LastBoundBO].LastLightComplexity){program->SetUniformf("specularIntensity", sIntensity);program->SetUniform3f("specularColorUniform", sColor);program->SetUniformf("specularPowerUniform", specularPower);}
...}

opacityUniform——透明度
ambientIntensity——环境光的强度
diffuseIntensity——漫反射光的强度
ambientColorUniform——环境光颜色
diffuseColorUniform——漫反射光颜色
specularIntensity——镜面光强度
specularColorUniform——镜面光颜色
specularPowerUniform——镜面光高光强度

void vtkOpenGLRenderer::UpdateLightingUniforms(vtkShaderProgram* program)
{
...double* dColor = light->GetDiffuseColor();double intensity = light->GetIntensity();
...{lightColor[0] = dColor[0] * intensity;lightColor[1] = dColor[1] * intensity;lightColor[2] = dColor[2] * intensity;}program->SetUniform3f((lcolor + count).c_str(), lightColor);
...}

lightColor0——灯光颜色,0代表的是灯光的序号。

用户如何控制渲染效果?

渲染效果的控制是通过设置着色器参数完成,但这些参数是内部参数,需要在用户能访问的对象(例如:vtkActor、vtkLight)中提供接口给用户来设置这些参数。

vtkActor属性设置:

以最前面的三张图的效果为例:

第一张图的设置为:

actor->GetProperty()->SetAmbient(1.0);
actor->GetProperty()->SetDiffuse(0.0);
actor->GetProperty()->SetSpecular(0.0);

第二张图的设置为:

actor->GetProperty()->SetAmbient(0.0);
actor->GetProperty()->SetDiffuse(1.0);
actor->GetProperty()->SetSpecular(0.0);

第三张图的设置为:

actor->GetProperty()->SetAmbient(0.5);
actor->GetProperty()->SetDiffuse(0.5);

actor->GetProperty()->SetSpecular(0.0);

可以看出,三张图不同的效果是通过改变环境光和漫反射光的强度实现的。

灯光设置

我们都知道,灯光对于渲染是非常重要的,为什么上面不需要对灯光进行设置?

class vtkRenderer : public vtkViewport
{
...vtkLight* CreatedLight;vtkLightCollection* Lights; 
...vtkTypeBool TwoSidedLighting;vtkTypeBool AutomaticLightCreation;   
...
};vtkRenderer::vtkRenderer()
{
...this->CreatedLight = nullptr;this->AutomaticLightCreation = 1;this->TwoSidedLighting = 1;
...this->Lights = vtkLightCollection::New();
...
}
void vtkOpenGLRenderer::DeviceRender()
{
...this->UpdateLights();
...
}int vtkOpenGLRenderer::UpdateLights()
{
...// create alight if neededif (!lightingCount){if (this->AutomaticLightCreation){vtkDebugMacro(<< "No lights are on, creating one.");this->CreateLight();lc->InitTraversal(sit);light = lc->GetNextLight(sit);ltime = lc->GetMTime();lightingCount = 1;lightingComplexity = light->GetLightType() == VTK_LIGHT_TYPE_HEADLIGHT ? 1 : 2;ltime = vtkMath::Max(ltime, light->GetMTime());}}
...
}void vtkRenderer::CreateLight()
{if (!this->AutomaticLightCreation){return;}if (this->CreatedLight){this->RemoveLight(this->CreatedLight);this->CreatedLight->UnRegister(this);this->CreatedLight = nullptr;}// I do not see why UnRegister is used on CreatedLight, but lets be// consistent.vtkLight* l = this->MakeLight();this->CreatedLight = l;this->CreatedLight->Register(this);this->AddLight(this->CreatedLight);l->Delete();this->CreatedLight->SetLightTypeToHeadlight();// set these values just to have a good default should LightFollowCamera// be turned off.this->CreatedLight->SetPosition(this->GetActiveCamera()->GetPosition());this->CreatedLight->SetFocalPoint(this->GetActiveCamera()->GetFocalPoint());
}

从上面的代码可以看出,当用户没有自己创建灯光时,VTK会自动创建一个灯光,并且灯光类型为HeadLight。

  • HeadLight:位于相机位置并指向焦点。
  • CameraLight:与HeadLight类似,但它不一定在相机位置。它定义在一个相机位于(0,0,1),朝向(0,0,0),距离为1,up方向为(0,1,0)的坐标空间中。
  • SceneLight:位于世界坐标空间中的光源。
class vtkLight : public vtkObject
{
...double Intensity;double AmbientColor[3];double DiffuseColor[3];double SpecularColor[3];
...
};vtkLight::vtkLight()
{
...this->DiffuseColor[0] = 1.0;this->DiffuseColor[1] = 1.0;this->DiffuseColor[2] = 1.0;
...this->Intensity = 1.0;
...
}

从上面的代码可以看到,自动创建的灯光的颜色为白光,强度为1。

要想控制灯光的强度,需要自己创建一个灯光,并关闭自动创建灯光开关,代码如下:

int main(int, char*[])
{
...vtkNew<vtkRenderer> renderer;renderer->SetAutomaticLightCreation(false);renderWindow->AddRenderer(renderer);vtkNew<vtkLight> light;light->SetLightTypeToHeadlight();light->SetDiffuseColor(1, 1, 1);light->SetIntensity(0.5);light->SetPosition(0, 0, 1);light->SetFocalPoint(0, 0, 0);renderer->AddLight(light);...
}

基于上面第三张图的设置加上光照强度之后的效果图如下:
actor->GetProperty()->SetAmbient(0.5);
actor->GetProperty()->SetDiffuse(0.5);
actor->GetProperty()->SetSpecular(0.0);
light->SetIntensity(0.5);

可以看到图相比之前变暗了。为什么会变暗呢?

下面是片段着色器的部分代码:

  vec3 specularColor = specularIntensity * specularColorUniform;
  float specularPower = specularPowerUniform;
  vec3 ambientColor = ambientIntensity * vertexColorVSOutput.rgb;
  vec3 diffuseColor = diffuseIntensity * vertexColorVSOutput.rgb;

  float opacity = opacityUniform * vertexColorVSOutput.a;

  //VTK::Edges::Impl

  // Generate the normal if we are not passed in one
  vec3 normalVCVSOutput = normalize(normalVCVSOutput);
  if (gl_FrontFacing == false) { normalVCVSOutput = -normalVCVSOutput; }
  //VTK::Normal::Impl

  float df = max(0.000001, normalVCVSOutput.z);
  float sf = pow(df, specularPower);
  vec3 diffuse = df * diffuseColor * lightColor0;
  vec3 specular = sf * specularColor * lightColor0;
  gl_FragData[0] = vec4(ambientColor + diffuse + specular, opacity);

从片段着色器的代码可以看到,调整光照强度,改变的是lightColor0的值,其会影响到漫反射颜色,但不会影响到环境光的颜色。

原先光照强度为1.0时,lightColor0 = (1, 1, 1)

后调整光照强度为0.5时,lightColor0 = (0.5, 0.5, 0.5)

vec3 diffuse = df * diffuseColor * lightColor0; 所以漫反射光的值变小,图就变暗了。另外,可以看出在这种片段着色器代码情况下,改变光照强度实际上与改变vtkActor属性的漫反射光强度是一致的,本质都是改变漫反射光的颜色。

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

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

相关文章

C++基础知识(四:类的学习)

类 类指的就是对同一类对象&#xff0c;把所有的属性都封装起来&#xff0c;你也可以把类看成一个高级版的结构体。 【1】定义 class 类名 { 访问权限:成员属性; 访问权限:成员方法; }访问权限&#xff1a; public:共有的&#xff0c;类内、类外和子类中都可以访问 private:私有…

接近于pi的程序

在一个平静的午后&#xff0c;两个神秘的数字悄然相遇了。它们分别是-1031158223和-328227871。这两个数字看起来普普通通&#xff0c;但谁知它们背后隐藏着一段令人惊叹的奇幻之旅。 这两个数字其实是π的两位探险家&#xff0c;它们决定通过一次除法运算来探索π的奥秘。它们…

怎么在线生成动态gif?这个网站一定要知道

静态图片是指一张固定的、不具有动态效果的图片。它通常是由像素点组成的&#xff0c;可以是照片、插图、图标等。静态图片只能呈现一种特定的场景或图像&#xff0c;不能展示动态变化。动态图片&#xff08;是由一系列静态图片组成的&#xff0c;通过快速连续播放这些画面&…

线程共享和非共享的资源及线程优缺点

注意&#xff1a;共享的内存地址空间中不包括栈&#xff1b;共享文件描述符表&#xff0c;表示&#xff0c;同一进程中线程可以操作同一文件。

使用代理IP技术实现爬虫同步获取和保存

概述 在网络爬虫中&#xff0c;使用代理IP技术可以有效地提高爬取数据的效率和稳定性。本文将介绍如何在爬虫中同步获取和保存数据&#xff0c;并结合代理IP技术&#xff0c;以提高爬取效率。 正文 代理IP技术是一种常用的网络爬虫技术&#xff0c;通过代理服务器转发请求&a…

力扣 48. 旋转图像

1.题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]]…

探索设计模式的魅力:状态模式揭秘-如何优雅地处理复杂状态转换

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;并且坚持默默的做事。 探索设计模式的魅力&#xff1a;状态模式揭秘-如何优雅地处理复杂状态转换 文章目录 一、案例…

HCIA-HarmonyOS设备开发认证V2.0-IOT硬件子系统-WatchDog

目录 一、 WATCHDOG 概述功能简介基本概念 二、WATCHDOG 模块相关API三、WATCHDOG HDF驱动开发3.1、开发步骤(待续...) 坚持就有收获 一、 WATCHDOG 概述 功能简介 看门狗&#xff08;Watchdog&#xff09;&#xff0c;又称看门狗计时器&#xff08;Watchdog timer&#xff0…

零基础学编程,编程简单学,中文编程工具下载及工具箱进度条构件的用法

一、前言 今天给大家分享的中文编程开发语言工具 进度条构件的用法。 编程入门视频教程链接 https://edu.csdn.net/course/detail/39036 编程工具及实例源码文件下载可以点击最下方官网卡片——软件下载——常用工具下载——编程工具免费版下载及实例源码下载。 进度条 进度…

涵盖5大领域的机器学习工具介绍

随着数据的产生及其使用量的不断增加&#xff0c;对机器学习模型的需求也在成倍增加。由于ML系统包含了算法和丰富的ML库&#xff0c;它有助于分析数据和做出决策。难怪机器学习的知名度越来越高&#xff0c;因为ML应用几乎主导了现代世界的每一个方面。随着企业对这项技术的探…

信息检索(二):Dense Passage Retrieval for Open-Domain Question Answering

Dense Passage Retrieval for Open-Domain Question Answering 摘要1. 引言2. 背景3. DPR4. 实验设置5. 实验&#xff1a;文章检索6. 实验&#xff1a;问题问答7. 相关工作8. 结论参考资料 原文链接&#xff1a;https://aclanthology.org/2020.emnlp-main.550.pdf DPR 最早引入…

六、回归与聚类算法 - K-means算法

目录 1、K-means 聚类步骤 2、API 3、案例 4、性能评估指标 5、总结 线性回归欠拟合与过拟合线性回归的改进 - 岭回归分类算法&#xff1a;逻辑回归模型保存与加载无监督学习&#xff1a;K-means算法 1、K-means 聚类步骤 2、API 3、案例 4、性能评估指标 5、总结

【数据结构与算法初学者指南】【冲击蓝桥篇】String与StringBuilder的区别和用法

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《数据结构与算法&#xff1a;初学者入门指南》&#x1f4d8;&am…

【 JS 进阶 】Web APIs (一)

“生命是一曲奇妙的交响&#xff0c;每一段都是挑战&#xff0c;每一个音符都是机遇。在激情的旋律中&#xff0c;用勇气弹奏&#xff0c;创造出属于自己的华彩人生。” - 贝多芬 了解 DOM 的结构并掌握其基本的操作&#xff0c;体验 DOM 的在开发中的作用 知道 ECMAScript 与 …

基于SpringBoot的家教管理系统

基于SpringBootVue的家教管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台主页 家教 个人中心 管理员界面 摘要 本文介绍了基于SpringBoot框架开发的家…

【深度学习笔记】3_5 图像分类数据集fashion-mnist

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 3.5 图像分类数据集&#xff08;Fashion-MNIST&#xff09; 在介绍softmax回归的实现前我们先引入一个多类图像分类数据集。它将在后面的章节中被多次使用&#xff0c…

论文是怎么一回事

最近找到女朋友了&#xff0c;她还挺关心我毕业和论文的事情&#xff0c;我开始着手弄论文了~ 说来惭愧&#xff0c;我一直以为读研就是做东西当作工作来完成&#xff0c;结果一直陷入如何实现的问题&#xff0c;结果要论文时不知道怎么弄创新点&#xff0c;这才转过头来弄论文…

信号系统之线性图像处理

1 卷积 图像卷积的工作原理与一维卷积相同。例如&#xff0c;图像可以被视为脉冲的总和&#xff0c;即缩放和移位的delta函数。同样&#xff0c;线性系统的特征在于它们如何响应脉冲。也就是说&#xff0c;通过它们的脉冲响应。系统的输出图像等于输入图像与系统脉冲响应的卷积…

重点媒体如何投稿?考核稿件投稿指南

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 机构组织&#xff0c;国企央企都需要定期将相关新闻投递到央媒&#xff0c;官媒&#xff0c;或者地方重点媒体中&#xff0c;那么如何进行投稿了&#xff0c;今天就与大家分享下。 央媒投…

喝多少瓶汽水

喝多少瓶汽水 题目描述&#xff1a;解法思路&#xff1a;解法代码&#xff1a;运行结果: 题目描述&#xff1a; 水已知1瓶汽水1元&#xff0c;2个空瓶可以换⼀瓶汽水&#xff0c;输入整数n&#xff08;n>0&#xff09;&#xff0c;表示n元钱&#xff0c;计算可以多少汽水&a…