3.8【Q】cv
这个draw_line函数的逻辑和功能是什么?代码思路是什么?怎么写的?
这个t是什么?t.v[0]和t.v[1],[2]又是什么?
void rst::rasterizer::draw(rst::pos_buf_id pos_buffer, rst::ind_buf_id ind_buffer, rst::Primitive type)
{if (type != rst::Primitive::Triangle){throw std::runtime_error("Drawing primitives other than triangle is not implemented yet!");}auto& buf = pos_buf[pos_buffer.pos_id];auto& ind = ind_buf[ind_buffer.ind_id];float f1 = (100 - 0.1) / 2.0;float f2 = (100 + 0.1) / 2.0;Eigen::Matrix4f mvp = projection * view * model;for (auto& i : ind){Triangle t;Eigen::Vector4f v[] = {mvp * to_vec4(buf[i[0]], 1.0f),mvp * to_vec4(buf[i[1]], 1.0f),mvp * to_vec4(buf[i[2]], 1.0f)};for (auto& vec : v) {vec /= vec.w();}for (auto & vert : v){vert.x() = 0.5*width*(vert.x()+1.0);vert.y() = 0.5*height*(vert.y()+1.0);vert.z() = vert.z() * f1 + f2;}for (int i = 0; i < 3; ++i){t.setVertex(i, v[i].head<3>());t.setVertex(i, v[i].head<3>());t.setVertex(i, v[i].head<3>());}t.setColor(0, 255.0, 0.0, 0.0);t.setColor(1, 0.0 ,255.0, 0.0);t.setColor(2, 0.0 , 0.0,255.0);rasterize_wireframe(t);}
}
这个draw函数的输入参数都是什么?有什么意义?内部处理逻辑是什么?
void rst::rasterizer::rasterize_triangle(const Triangle& t) {auto v = t.toVector4();// TODO : Find out the bounding box of current triangle.// iterate through the pixel and find if the current pixel is inside the triangle// If so, use the following code to get the interpolated z value.//auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v);//float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());//float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();//z_interpolated *= w_reciprocal;// TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
}
这里为什么有一个“ auto v = t.toVector4();”操作?作用是什么?
什么叫“支持透视投影下的正确深度插值和透视校正属性插值”?还是没理解,形象地说明?为什么要拓展到四维?
void rst::rasterizer::rasterize_triangle(const Triangle& t) {auto& v0 = t.v;auto& v1 = t.v;auto& v2 = t.v;// 计算三角形的包围盒float min_x = std::min({v0.x(), v1.x(), v2.x()});float max_x = std::max({v0.x(), v1.x(), v2.x()});float min_y = std::min({v0.y(), v1.y(), v2.y()});float max_y = std::max({v0.y(), v1.y(), v2.y()});
这些 v0,v1,v2是什么意思?原代码里写的不是 auto v = t.toVector4();吗?
void rst::rasterizer::rasterize_triangle(const Triangle& t) {auto v = t.toVector4();// 计算包围盒float min_x = std::min({t.a().x(), t.b().x(), t.c().x()});float max_x = std::max({t.a().x(), t.b().x(), t.c().x()});float min_y = std::min({t.a().y(), t.b().y(), t.c().y()});float max_y = std::max({t.a().y(), t.b().y(), t.c().y()});// 转换为整数像素范围并钳位int x_begin = std::max(static_cast<int>(std::floor(min_x)), 0);int x_end = std::min(static_cast<int>(std::ceil(max_x)), width);int y_begin = std::max(static_cast<int>(std::floor(min_y)), 0);int y_end = std::min(static_cast<int>(std::ceil(max_y)), height);// 遍历包围盒内的所有像素for (int x = x_begin; x < x_end; ++x) {for (int y = y_begin; y < y_end; ++y) {float center_x = x + 0.5f;float center_y = y + 0.5f;if (insideTriangle(center_x, center_y, t)) {// 计算重心坐标Eigen::Vector2f A(v0.x(), v0.y());Eigen::Vector2f B(v1.x(), v1.y());Eigen::Vector2f C(v2.x(), v2.y());Eigen::Vector2f P(center_x, center_y);float denominator = (B.y() - C.y()) * (A.x() - C.x()) + (C.x() - B.x()) * (A.y() - C.y());if (denominator == 0) continue;float u = ((B.y() - C.y()) * (P.x() - C.x()) + (C.x() - B.x()) * (P.y() - C.y())) / denominator;float v = ((C.y() - A.y()) * (P.x() - C.x()) + (A.x() - C.x()) * (P.y() - C.y())) / denominator;float w = 1 - u - v;if (u >= 0 && v >= 0 && w >= 0) {// 插值深度float z_interpolated = u * v0.z() + v * v1.z() + w * v2.z();int index = get_index(x, y);// 深度测试if (z_interpolated < depth_buf[index]) {// 颜色插值Eigen::Vector3f color = u * t.color + v * t.color + w * t.color;set_pixel(Eigen::Vector3f(x, y, 1.0f), color);depth_buf[index] = z_interpolated;}}}}} // TODO : Find out the bounding box of current triangle.// iterate through the pixel and find if the current pixel is inside the triangle// If so, use the following code to get the interpolated z value.//auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v);//float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());//float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();//z_interpolated *= w_reciprocal;// TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
}
在遍历包围盒内所有像素时,为什么要定义出center_x和center_y?在计算重心坐标时,各行代码操作的意义和作用又是什么?
在
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
auto v = t.toVector4();中,为什么一开始要定义出一个v?v在后续的计算中有什么用?
这个v的w维度,是在传入t后进行扩展的,并没有经过mvp矩阵的变化,那么三个点的w维度上的值不都是1吗?后面 float w_reciprocal = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());又有什么意义?
不是,mvp矩阵是在draw函数中进行计算的,在draw函数最后调用了rasterize_triangle(t);,在rasterize_triangle(t);中配置auto v = t.toVector4();,那么t的第四维度w不该是1吗?mvp矩阵并没有在此时发挥作用?
static bool insideTriangle(int x, int y,const Vector3f* _v)
{ Vector3f P(x+0.5f,y+0.5f,1.0f);const Vector3f& A = _v[0];const Vector3f& B = _v[1];const Vector3f& C = _v[2];// 计算三个边的向量和点P到顶点的向量Vector3f AB = B - A;Vector3f BC = C - B;Vector3f CA = A - C;Vector3f AP = P - A;Vector3f BP = P - B;Vector3f CP = P - C;// 计算叉积符号float cross1 = AB.cross(AP).z();float cross2 = BC.cross(BP).z();float cross3 = CA.cross(CP).z();// 检查符号是否一致return (cross1 > 0 && cross2 > 0 && cross3 > 0) || (cross1 < 0 && cross2 < 0 && cross3 < 0);// TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]
}
这段代码能实现判断点是否在内外部的原理是什么?cross1等取z是什么意思?有什么意义?
为什么Vector3f P(x+0.5f,y+0.5f,1.0f);可以确保测试点为像素中心?什么叫像素中心?为什么要保证在像素中心?
static std::tuple<float, float, float> computeBarycentric2D(float x, float y, const Vector3f* v)
{float c1 = (x*(v[1].y() - v[2].y()) + (v[2].x() - v[1].x())*y + v[1].x()*v[2].y() - v[2].x()*v[1].y()) / (v[0].x()*(v[1].y() - v[2].y()) + (v[2].x() - v[1].x())*v[0].y() + v[1].x()*v[2].y() - v[2].x()*v[1].y());float c2 = (x*(v[2].y() - v[0].y()) + (v[0].x() - v[2].x())*y + v[2].x()*v[0].y() - v[0].x()*v[2].y()) / (v[1].x()*(v[2].y() - v[0].y()) + (v[0].x() - v[2].x())*v[1].y() + v[2].x()*v[0].y() - v[0].x()*v[2].y());float c3 = (x*(v[0].y() - v[1].y()) + (v[1].x() - v[0].x())*y + v[0].x()*v[1].y() - v[1].x()*v[0].y()) / (v[2].x()*(v[0].y() - v[1].y()) + (v[1].x() - v[0].x())*v[2].y() + v[0].x()*v[1].y() - v[1].x()*v[0].y());return {c1,c2,c3};
}
这个函数是在干什么?有什么用?传入参数的意义和输出是什么意思?
std::tie(alpha, beta, gamma) = tup;
这句什么意思?tie什么意思?
//MSAA 4Xif (MSAA) {// 格子里的细分四个小点坐标std::vector<Eigen::Vector2f> pos{{0.25,0.25},{0.75,0.25},{0.25,0.75},{0.75,0.75},};for (int x = min_x; x <= max_x; x++) {for (int y = min_y; y <= max_y; y++) {// 记录最小深度float minDepth = FLT_MAX;// 四个小点中落入三角形中的点的个数int count = 0;// 对四个小点坐标进行判断 for (int i = 0; i < 4; i++) {// 小点是否在三角形内if (insideTriangle((float)x + pos[i][0], (float)y + pos[i][1], t.v)) {// 如果在,对深度z进行插值auto tup = computeBarycentric2D((float)x + pos[i][0], (float)y + pos[i][1], t.v);float alpha;float beta;float gamma;// std::tie表示打散tup到 alpha beta gamma三个分量std::tie(alpha, beta, gamma) = tup;// reciprocal 倒数float w_reciprocal = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());// 按照三角形三个点的权重,对当前点插值,求出z值,注意,这里的reciprocal用的有点莫名其妙,先不用管// 而且alpha beta gamma用起来是需要矫正的// 此处留个疑问:为什么不能在投影变换时,求出每个点的z坐标映射值呢?float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();z_interpolated *= w_reciprocal;// 求出当前点中四个小点对应的深度,以代表当前点的z值,用来和其他点的z做对比minDepth = std::min(minDepth, z_interpolated);// 包含一个点count +1count++;}}if (count != 0) {if (depth_buf[get_index(x, y)] > minDepth) {// 简单的对color/4也可以,处理的比较粗糙。// 注意getColor其实就只用了一个值,三角形三个点的颜色相同// 这里还考虑了当前缓冲里面存贮的颜色值Vector3f color = t.getColor()*count/4 + (4-count)*frame_buf[get_index(x,y)]/4;Vector3f point(3);point << (float)x, (float)y, minDepth;// 替换深度depth_buf[get_index(x, y)] = minDepth;// 修改颜色set_pixel(point, color);}}}}}
详细解释这段代码每一句的作用和意义?如何实现MSAA抗锯齿的?
Vector3f color = t.getColor()*count/4 + (4-count)*frame_buf[get_index(x,y)]/4;这个color的计算是什么意思?怎么做的?
为什么不能在投影变换时,求出每个点的z坐标映射值呢?什么意思?思路是什么?
当前代码开启了超采样,但是if (count != 4)std::cout << "current count test: " << count << '\n';并没有输出,说明count要么是0要么是4,为什么会发生这种情况?为什么?如何处理?使其去锯齿?
就是这个函数static bool insideTriangle(float x, float y,const Vector3f* _v)的传入参数一开始设置为int的原因;此外,想要进一步提升抗锯齿的效果,该怎么做?给出修改代码
/ 修改后的抗锯齿核心逻辑
void rst::rasterizer::rasterize_triangle(const Triangle& t) {auto v = t.toVector4();// 8x旋转采样点布局std::vector<Eigen::Vector2f> pos { /* 上述8个点 */ };// 包围盒扩展(增加1像素冗余)min_x = static_cast<int>(std::floor(min_x - 1.0f));max_x = static_cast<int>(std::ceil(max_x + 1.0f));for (int x = min_x; x <= max_x; x++) {for (int y = min_y; y <= max_y; y++) {int count = 0;float minDepth = FLT_MAX;// 第一层8x采样for (int i=0; i<8; ++i) {float sx = x + pos[i][0], sy = y + pos[i][1];if (insideTriangle(sx, sy, t.v)) {// 计算深度...count++;}}// 边缘区域二次采样if (count>0 && count<8) {std::vector<Eigen::Vector2f> edge_pos {/* 4个点 */};for (auto& ep : edge_pos) {if (insideTriangle(x+ep[0], y+ep[1], t.v)) count++;}}// 深度加权颜色混合if (count > 0) {float weight = count / 12.0; // 最大12采样Vector3f color = /* 加权混合公式 */;set_pixel(point, color);}}}// 后处理阶段post_process();
}
完成这个代码里省略的部分
增加采样数量后,在原来4*的基础上,8*的图形边缘出现了黑边,且抗锯齿效果并没有显著提升,甚至有所倒退,这是为什么?
相关文章:
3.8【Q】cv
这个draw_line函数的逻辑和功能是什么?代码思路是什么?怎么写的? 这个t是什么?t.v[0]和t.v[1],[2]又是什么? void rst::rasterizer::draw(rst::pos_buf_id pos_buffer, rst::ind_buf_id ind_buffer, rst::Primitive ty…...
upload-labs文件上传
第一关 上传一个1.jpg的文件,在里面写好一句webshell 保留一个数据包,将其中截获的1.jpg改为1.php后重新发送 可以看到,已经成功上传 第二关 写一个webshell如图,为2.php 第二关在过滤tpye的属性,在上传2.php后使用b…...
PyTorch中Tensor对象的属性和方法
目录 一、核心属性 复数支持 转置与视图操作 元信息 梯度相关 二. 常用方法 基本操作 转置与视图 数学运算 深度学习相关 3. 使用示例 梯度计算 设备管理 自定义反向传播 4. 注意事项 总结 一、核心属性 1.requires_grad: _bool: 该…...
C++20 格式化库:强大的字符串格式化工具
文章目录 格式化语法常见用法1. 填充和对齐2. 数值格式化3. 进制格式化4. 自定义类型 示例代码注意事项 C20 的格式化库是一个强大的工具,用于处理字符串的格式化操作。它提供了类似于 Python 中 str.format() 的功能,但语法和用法更符合 C 的风格。以下…...
[傻瓜式教学]如何将MathType公式编辑器内嵌到WPS工具栏中
[傻瓜式教学]如何将MathType公式编辑器内嵌到WPS工具栏中 将MathType公式编辑器内嵌到WPS工具栏中 下载好所需文件 我用夸克网盘分享了「mathtype安装教程超简单易上手.zip」,点击链接即可保存。打开「夸克APP」 链接:https://pan.quark.cn/s/4726c684…...
分析TCP三次握手与四次挥手
TCP(传输控制协议)通过三次握手建立连接,四次挥手终止连接,确保数据传输的可靠性。 TCP的三个控制标志位: SYN——用于建立连接,同步序列号。 ACK——用于确认收到的数据。 FIN——用于终止连接。 ISN…...
【深度学习】宠物品种分类Pet Breeds Classifier
文章目录 宠物品种数据集制作宠物品种标签图像预处理Presizing 损失函数loss观察模型的性能提升模型的性能learning rate finder使用CLR算法训练选择学习率的策略重新训练 迁移学习微调fine_tunefit_one_cycle有判别力的学习率 选择epoch的数量更深的网络架构 宠物品种数据集 …...
【从零开始学习计算机科学】HLS算子调度
算子调度 调度是HLS 中的核心问题,为无时序或部分时序的输入指定时钟边界,其对最终结果质量具有很大的影响。调度会影响时钟频率、延时、吞吐率、面积、功耗等多种因素。 调度的输入是控制数据流图,其节点表示算子/操作,有向边表示数据依赖,控制依赖,优先依赖。如果没有…...
centos 安装composer 教程
打开命令行 php -r "copy(https://getcomposer.org/installer, composer-setup.php);" sudo php composer-setup.php --install-dir/usr/local/bin --filenamecomposer composer --version sudo chmod us /usr/local/bin/composer Super18120/article/details/14388…...
C语言_数据结构总结2:动态分配方式的顺序表
0——静态分配内存的顺序表和动态分配内存的顺序表的相同之处和不同之处 相同之处 基本操作逻辑相同:无论是静态分配还是动态分配的顺序表,其核心的操作逻辑是一致的。例如插入操作都需要将插入位置之后的元素依次后移,删除操作都需要将删除…...
嵌入式人工智能应用-第6章 人脸检测
嵌入式人工智能应用 人脸检测 嵌入式人工智能应用1 人脸检测1.1 CNN 介绍1.2 人脸检测原理1.3 MTCNN介绍1.4 NCNN介绍2 系统安装2.1 安装依赖库NCNN2.2 运行对应的库3 总结1 人脸检测 1.1 CNN 介绍 卷积神经网络。卷积是什么意思呢?从数学上说,卷积是一种运算。它是我们学习…...
关于无感方波启动预定位阶段
一、预定位的核心目标与原理 消除启动不确定性 无位置传感器下,转子初始位置未知,直接换相可能导致反转或失步。预定位通过施加固定方向磁场,强制转子对齐至预定角度(通常0或60电角度),建立初始位置基准。 …...
WSL安装及问题
1 概述 Windows Subsystem for Linux(简称WSL)是一个在Windows 10\11上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层。它是由微软与Canonical公司合作开发,开发人员可以在 Windows 计算机上同时访问 Windows 和…...
MySQL中的脏读与幻读:概念、影响与解决方案
在数据库事务处理中,脏读和幻读是两种常见的并发问题,可能导致数据不一致或逻辑错误。本文将结合实际场景,深入解析两者的原理及解决方案。 一、脏读(Dirty Read) 1. 概念解析 脏读指一个事务读取了另一个事务未提交…...
基于SpringBoot的商城管理系统(源码+部署教程)
运行环境 数据库:MySql 编译器:Intellij IDEA 前端运行环境:node.js v12.13.0 JAVA版本:JDK 1.8 主要功能 基于Springboot的商城管理系统包含管理端和用户端两个部分,主要功能有: 管理端 首页商品列…...
HeidiSQL:一款免费的数据库管理工具
HeidiSQL 是一款免费的图形化数据库管理工具,支持 MySQL、MariaDB、Microsoft SQL、PostgreSQL、SQLite、Interbase 以及 Firebird,目前只能在 Windows 平台使用。 HeidiSQL 的核心功能包括: 免费且开源,所有功能都可以直接使用。…...
Ae 效果详解:VR 色差
Ae菜单:效果/沉浸式视频/VR 色差 Immersive Video/VR Chromatic Aberrations VR 色差 VR Chromatic Aberrations效果用于模拟镜头色散现象,在 VR 视频中制造 RGB 通道错位的色彩偏移,以增强视觉风格或创造数字失真效果。 本效果适用于所有色深…...
计算机毕业设计SpringBoot+Vue.js制造装备物联及生产管理ERP系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Ubuntu 安装docker docker-compose
Docker 通过提供轻量级、可移植且高效的解决方案,简化了软件开发和部署。“docker build”命令是 Docker 镜像创建过程的核心。本文将探讨 Docker 构建命令、用法以及 Docker 构建的优化。 Docker 构建有什么作用? Docker build 是一个命令行界面 CLI命…...
【Linux内核系列】:深入解析输出以及输入重定向
🔥 本文专栏:Linux 🌸作者主页:努力努力再努力wz ★★★ 本文前置知识: 文件系统以及文件系统调用接口 用c语言简单实现一个shell外壳程序 内容回顾 那么在此前的学习中,我们对于Linux的文件系统已经有了…...
【linux网络编程】端口
一、端口(Port)概述 在计算机网络中,端口(Port) 是用来标识不同进程或服务的逻辑通信端点。它类似于一座大楼的房间号,帮助操作系统和网络协议区分不同的应用程序,以便正确地传输数据。 1. 端口…...
PyTorch系列教程:Tensor.view() 方法详解
这篇简明扼要的文章是关于PyTorch中的tensor.view()方法的介绍与应用,与reshape()方法的区别,同时给出示例进行详细解释。 Tensor基础 Tensor(张量)的视图是一个新的Tensor,它与原始Tensor共享相同的底层数据,但具有不同的形状或…...
软件测试的基础入门(二)
文章目录 一、软件(开发)的生命周期什么是生命周期软件(开发)的生命周期需求分析计划设计编码测试运行维护 二、常见的开发模型瀑布模型流程优点缺点适应的场景 螺旋模型流程优点缺点适应的场景 增量模型和迭代模型流程适应的场景…...
Springboot + minio
参考: SpringBoot整合Minio_springboot minio-CSDN博客 <!--minio 依赖--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.11</version></dependency> applicaio…...
地下变电站如何实现安全智能运营-以110kV站为例看环境监测与设备联控
1、地下变电站简介 在经济发达的地区,由于城市中心土地资源紧张、征地拆迁费用昂贵,因此采用地下变电站来解决这些问题不失为一个好的途径和思路。地下变电站一般采用室内全封闭式组合电气设备,220&#x…...
windows无界面后台定时任务 (重启自启动,ODBS为例)
一、前言 mdb(Microsoft Database)是Microsoft Access中使用的一种数据存储格式,可以通过ODBC驱动程序进行访问和操作,在Python中也可以安装相应模块打开。 这是我在项目中更新bs数据的一个实践记录,结合windows定时一起记录一下,方便以后照搬~ 二、安装 Python安装库…...
FPGA 实验报告:四位全加器与三八译码器仿真实现
目录 安装Quartus软件 四位全加器 全加器、半加器 半加器: 全加器: 四位全加器电路图 创建项目 半加器 全加器 四位全加器 代码实现 半加器 全加器 四位全加器 三八译码器 创建项目 代码展示 modelsim仿真波形图 四位全加器 三八译码…...
win11 Visual Studio 17 2022源码编译 opencv4.11.0 + cuda12.6.3 启用GPU加速
win11 Visual Studio 17 2022 源码编译 opencv4.11.0 cuda12.6.3 启用GPU加速 配置: 生成 opencv 生成 opencv-python 1 下载源码和安装软件 win11 x64 系统 安装Visual Studio 17 2022 下载opencv4.11.0 源码 https://github.com/opencv/opencv/releases/tag/4.11.0 下载…...
Ribbon实现原理
文章目录 概要什么是Ribbon客户端负载均衡 RestTemplate核心方法GET 请求getForEntitygetForObject POST 请求postForEntitypostForObjectpostForLocation PUT请求DELETE请求 源码分析类图关系 与Eureka结合重试机制 概要 什么是Ribbon Spring Cloud Ribbon是一个基于HTTP和T…...
MuMu-LLaMA:通过大型语言模型进行多模态音乐理解和生成(Python代码实现+论文)
MuMu-LLaMA 模型是一种音乐理解和生成模型,能够进行音乐问答以及从文本、图像、视频和音频生成音乐,以及音乐编辑。该模型利用了用于音乐理解的 MERT、用于图像理解的 ViT 和用于视频理解的 ViViT 等编码器,以及作为音乐生成模型(…...
