opengl对图像进行腐蚀和膨胀
效果图
膨胀的原理:
膨胀就是求局部最大值的操作,就是给定一个核对图像进行卷积操作,见下图
将核B与图像A卷积,即计算B覆盖区域的像素点的最大值,并把这个最大值赋给参考点指定的像素,这样
就会使图像中的高亮区域逐渐增长,这就是膨胀的效果,膨胀的数学表达式
opengl中膨胀效果的shader实现
varying vec2 V_Texcoord;
uniform sampler2D U_MainTexture;void main()
{vec4 maxValue=vec4(0.0);int coreSize=3;//卷积核的尺寸 3x3int halfCoreSize=coreSize/2;float texelOffset=1/100.0;//纹理坐标偏移量for(int y=0;y<coreSize;y++){for(int x=0;x<coreSize;x++){//计算卷积核覆盖区域像素点的最大值vec4 color=texture2D(U_MainTexture,V_Texcoord+vec2((-halfCoreSize+x)*texelOffset,(-halfCoreSize+y)*texelOffset));maxValue=max(maxValue,color);}}gl_FragColor=maxValue;}
腐蚀的原理:
腐蚀和膨胀相反,就局部最小值,腐蚀示意图
腐蚀的数学表达式
opengl中腐蚀的shader实现
varying vec2 V_Texcoord;uniform sampler2D U_MainTexture;void main()
{vec4 minValue=vec4(1.0);int coreSize=6;int halfCoreSize=coreSize/2;float texelOffset=1/100.0;//遍历核for(int y=0;y<coreSize;y++){for(int x=0;x<coreSize;x++){//计算核B覆盖区域的像素点的最小值vec4 currentAlpha=texture2D(U_MainTexture,V_Texcoord+vec2((-halfCoreSize+x)*texelOffset,(-halfCoreSize+y)*texelOffset));minValue=min(minValue,currentAlpha);}}gl_FragColor=minValue;
}
渲染入口
#include <windows.h>
#include "glew.h"
#include <stdio.h>
#include <math.h>
#include "utils.h"
#include "GPUProgram.h"
#include "ObjModel.h"
#include "FBO.h"
#include "FullScreenQuad.h"
#include "Glm/glm.hpp"
#include "Glm/ext.hpp"
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glew32.lib")LRESULT CALLBACK GLWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
WNDCLASSEX wndClass;
wndClass.cbClsExtra = 0;
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.cbWndExtra = 0;
wndClass.hbrBackground = NULL;
wndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndClass.hIcon = NULL;
wndClass.hIconSm = NULL;
wndClass.hInstance = hInstance;
wndClass.lpfnWndProc=GLWindowProc;
wndClass.lpszClassName = L"OpenGL";
wndClass.lpszMenuName = NULL;
wndClass.style = CS_VREDRAW | CS_HREDRAW;
ATOM atom = RegisterClassEx(&wndClass); RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = 1280;
rect.bottom = 720;
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
HWND hwnd = CreateWindowEx(NULL, L"OpenGL", L"RenderWindow", WS_OVERLAPPEDWINDOW, 100, 100, rect.right-rect.left, rect.bottom-rect.top, NULL, NULL, hInstance, NULL);
HDC dc = GetDC(hwnd);
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_TYPE_RGBA | PFD_DOUBLEBUFFER;
pfd.iLayerType = PFD_MAIN_PLANE;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8; int pixelFormatID = ChoosePixelFormat(dc, &pfd); SetPixelFormat(dc,pixelFormatID,&pfd); HGLRC rc = wglCreateContext(dc);
wglMakeCurrent(dc, rc);
GetClientRect(hwnd, &rect);
int viewportWidth = rect.right - rect.left, viewportHeight = rect.bottom - rect.top;
glewInit(); GPUProgram originalProgram;
originalProgram.AttachShader(GL_VERTEX_SHADER, "Debug/res/shader/fullscreenquad.vs");
originalProgram.AttachShader(GL_FRAGMENT_SHADER, "Debug/res/shader/fullscreenquad.fs");
originalProgram.Link();
originalProgram.DetectAttribute("pos");
originalProgram.DetectAttribute("texcoord");
originalProgram.DetectUniform("U_MainTexture"); GPUProgram erosionProgram;
erosionProgram.AttachShader(GL_VERTEX_SHADER, "Debug/res/shader/fullscreenquad.vs");
erosionProgram.AttachShader(GL_FRAGMENT_SHADER, "Debug/res/shader/Erosion.fs");
erosionProgram.Link();
erosionProgram.DetectAttribute("pos");
erosionProgram.DetectAttribute("texcoord");
erosionProgram.DetectUniform("U_MainTexture"); GPUProgram dilationProgram;
dilationProgram.AttachShader(GL_VERTEX_SHADER, "Debug/res/shader/fullscreenquad.vs");
dilationProgram.AttachShader(GL_FRAGMENT_SHADER, "Debug/res/shader/Dilation.fs");
dilationProgram.Link();
dilationProgram.DetectAttribute("pos");
dilationProgram.DetectAttribute("texcoord");
dilationProgram.DetectUniform("U_MainTexture"); GPUProgram gpuProgram;
gpuProgram.AttachShader(GL_VERTEX_SHADER, "Debug/res/shader/x_ray.vs");
gpuProgram.AttachShader(GL_FRAGMENT_SHADER, "Debug/res/shader/x_ray.fs");
gpuProgram.Link(); gpuProgram.DetectAttribute("pos");
gpuProgram.DetectAttribute("texcoord");
gpuProgram.DetectAttribute("normal");
gpuProgram.DetectUniform("M");
gpuProgram.DetectUniform("V");
gpuProgram.DetectUniform("P");
gpuProgram.DetectUniform("NM");
gpuProgram.DetectUniform("U_EyePos");
//init 3d model
ObjModel cube,quad;
cube.Init("Debug/res/model/Sphere.obj");
//cube.Init("res/model/Quad.obj"); float identity[] = {
1.0f,0,0,0,
0,1.0f,0,0,
0,0,1.0f,0,
0,0,0,1.0f
};
float eyePos[] = { -0.5f, 1.5f, -3.0f }; glm::mat4 model1 = glm::translate<float>(-2.0f, 0.0f, -6.0f)*glm::rotate(-30.0f, 1.0f, 1.0f, 1.0f);
glm::mat4 projectionMatrix = glm::perspective(50.0f, (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.0f);
glm::mat4 viewMatrix1 = glm::lookAt(glm::vec3(-0.5f, 1.5f, -3.0f), glm::vec3(-2.0f, 0.0f, -6.0f), glm::vec3(0.0f, 1.0f, 0.0f)); glm::mat4 normalMatrix1 = glm::inverseTranspose(model1); FullScreenQuad fsq;
fsq.Init();
FBO fbo;
fbo.AttachColorBuffer("color", GL_COLOR_ATTACHMENT0, GL_RGBA, viewportWidth, viewportHeight);
fbo.AttachDepthBuffer("depth", viewportWidth, viewportHeight);
fbo.Finish(); ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_DEPTH_TEST);
MSG msg;
while (true)
{
if (PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//将球模型绘制到fbo
fbo.Bind();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glUseProgram(gpuProgram.mProgram);
glUniformMatrix4fv(gpuProgram.GetLocation("P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glUniform3fv(gpuProgram.GetLocation("U_EyePos"), 1, eyePos);
glUniformMatrix4fv(gpuProgram.GetLocation("M"), 1, GL_FALSE, glm::value_ptr(model1));
glUniformMatrix4fv(gpuProgram.GetLocation("V"), 1, GL_FALSE, glm::value_ptr(viewMatrix1));
glUniformMatrix4fv(gpuProgram.GetLocation("NM"), 1, GL_FALSE, glm::value_ptr(normalMatrix1));
cube.Bind(gpuProgram.GetLocation("pos"), gpuProgram.GetLocation("texcoord"), gpuProgram.GetLocation("normal"));
cube.Draw();
glDisable(GL_BLEND);
fbo.Unbind(); //将fbo里面已经绘制好的球模型作为纹理 贴到不同位置的四边形上用glUseProgram切换shader实现不同的效果
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(originalProgram.mProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbo.GetBuffer("color"));
glUniform1i(originalProgram.GetLocation("U_MainTexture"), 0);
fsq.DrawToLeftTop(originalProgram.GetLocation("pos"), originalProgram.GetLocation("texcoord")); glUseProgram(erosionProgram.mProgram);
fsq.DrawToRightTop(erosionProgram.GetLocation("pos"), erosionProgram.GetLocation("texcoord")); glUseProgram(dilationProgram.mProgram);
fsq.DrawToLeftBottom(dilationProgram.GetLocation("pos"), dilationProgram.GetLocation("texcoord")); glBindTexture(GL_TEXTURE_2D, 0);
glFlush();
SwapBuffers(dc);
}
return 0;
}
opengl对图像进行腐蚀和膨胀相关推荐
- 详解图像形态学操作之图形的腐蚀和膨胀的概念和运算过程,并利用OpenCV的函数erode()和函数dilate()对图像进行腐蚀和膨胀操作
图像形态学中两种最基本的操作就是对图形的腐蚀和膨胀,可以说,形态学中的中高级操作都是建立在这两种操作之上.通过这两种基本的运算可以去除图像中的噪声,分割出独立的区域或者将两个区域连接在一起. 关于图像 ...
- cuda学习笔记5——CUDA实现图像形态学腐蚀、膨胀
cuda学习笔记5--CUDA实现图像形态学腐蚀.膨胀 代码 linux如何编译cuda和opencv代码 耗时情况 代码 #include "cuda_runtime.h" #i ...
- 简单说说我理解的图像的腐蚀和膨胀
写这篇文章的时候在想办法搞opencv,看着课上教的莫名其妙,直接给我整不会了,借此机会记下来怎么腐蚀和膨胀 腐蚀 这里借一下图,原帖(5条消息) 图像的腐蚀与膨胀_张齐贤的博客-CSDN博客_腐蚀膨 ...
- OpenCV学习(12) 图像的腐蚀与膨胀(3)
通过使用不同的结构元素来进行膨胀腐蚀操作,可以检测图像中的角点,下面就一步一步看这个算法如果实现角点检测. 原图像: 首先我们创建四个结构元素 先用十字结构元素对原图像进行膨胀操作,得到下面的图像 再 ...
- opencv 图像的腐蚀与膨胀
形态学操作就是基于形状的一系列图像处理操作.通过将 结构元素 作用于输入图像来产生输出图像. 最基本的形态学操作有二:腐蚀与膨胀(Erosion 与 Dilation). 他们的运用广泛: 消除噪声 ...
- matlab图像的腐蚀和膨胀_OpenCV图像处理系列八 --- 腐蚀与膨胀
今天,我们一起来学习图像形态学操作中两种最基本的形态学操作,即腐蚀与膨胀. 一.理论 数学形态学(Mathematical morphology) 是一门建立在格论和拓扑学基础之上的图像分析学科,是数 ...
- pytorch实现图像的腐蚀和膨胀
前言: 之所以想到用 pytorch ,主要是因为不想在网络模块中调用 opencv 的函数. 调用 opencv 函数的基本步骤如下:先把 pytorch 的 tensor 转到 cpu 上,然后转 ...
- 图像形态学概要-腐蚀、膨胀、开运算、闭运算、形态学梯度(形态学边缘提取)、顶帽操作、黑帽操作
图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 图像形态学中两种最基本的操作就是对图形的腐蚀和膨 ...
- 基于python的opencv图像形态学处理(图像腐蚀与膨胀操作以及礼帽与黑帽)
腐蚀与膨胀 图像的腐蚀与膨胀互为逆向操作,通常用于处理二值图像(黑白图,以黑色为底面背景),因此需要先进行二值化处理,腐蚀和膨胀通俗的理解就是,在指定大小的卷积核内,如果该卷积核内全为黑色或全为白色, ...
最新文章
- 什么是结构风险?在决策树类相关算法中通常有哪些正则化参数来控制模型的结构风险?解读一下
- 今天开始SOA-阿里dubbo
- NYOJ 647 奋斗的小蜗牛在请客
- python随机数种子通俗_随机数种子random.seed()理解
- 一次thinkphp框架 success跳转卡顿问题的解决
- java 广义表_java 输入广义表 生成二叉树 | 学步园
- 机试题型_2020年焊工(技师)新版试题及焊工(技师)试题及答案
- java.lang.IllegalArgumentException: Request header is too large
- 网友疯买、雷军力撑,又一家国货站起来了!
- linux mmap实例_Linux下通过共享内存和mmap实现进程间通讯(含实例)
- Function.prototype.bind、call与apply方法简介
- SQL Server 2000 Service Pack 4 升级指南
- 【VMCloud云平台进阶篇】应用层面优化
- 计算机Java毕设项目-PPT答辩篇
- 彻底卸载vscode Linux,Ubuntu vscode 安装与卸载
- 摘录3:没有趋势,没有背驰。
- 【译】可扩展前端2  —  常见模式
- Flying-Saucer使用HTML或者FTL(Freemarker模板)生成PDF
- 喜什么颜什么的成语(喜什么颜什么四字成语大全)
- Dev-C++下面的编译状态栏信息不显示