GAMES101闫令琪图形学作业1(配置opencv4.5.4,并解决常见错误)
Posted hans774882968
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GAMES101闫令琪图形学作业1(配置opencv4.5.4,并解决常见错误)相关的知识,希望对你有一定的参考价值。
宿主机:Windows10;虚拟机:Ubuntu20.04。
下载
- opencv4.5.4:https://opencv.org/releases/
- opencv_contrib4.5.4:https://github.com/opencv/opencv_contrib/releases/tag/4.5.4
unzip opencv-4.5.4.zip
unzip opencv_contrib-4.5.4.zip
注意,两个文件夹要放在同一个文件夹(我命名为opencv)下,目录结构:
opencv
build
opencv-4.5.4
opencv_contrib-4.5.4
编译opencv
opencv似乎只支持编译源码,🤮。下面几条命令摘抄自参考链接1(官方文档)。在一条一条复制它们之前,需要注意:
- 很容易被官方文档4.5.4误导,以为不用装依赖。但踩坑后的感想:一定一定要先装依赖!如果不装依赖,编译opencv和项目都不会报错,但一运行就报错!于是你又要返回来先装依赖,然后重新编译opencv,相当于之前编译那么长时间都是白搭!!!
- canberra-gtk-module没有在4.4.0列出,但必须装(《常见错误》1)。
- 官方文档4.4.0用的是apt-get,4.5.4用的却是apt。建议还是不要混用,统一用apt吧!
- build那一步可能会卡死,解决方案见《常见错误》3。
- ”-j2“表示并行编译,参考Assignment1.pdf配置即可。
- 如果build时不幸遇到了这个错误:
CMake Error: failed to create symbolic link '../../lib/libopencv_core.so': operation not permitted
(《常见错误》2),这是因为包放在了挂载共享目录下,必须换一个非挂载文件夹,然后从头开始重新编译!
# 装依赖(摘抄自官方文档的4.4.0)
[compiler] sudo apt-get install build-essential
[required] sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
[optional] sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
# 官方文档还漏了一个required
sudo apt-get install libcanberra-gtk-module
# 以下几条命令摘抄自官方文档的4.5.4
# Install minimal prerequisites (Ubuntu 18.04 as reference)
sudo apt update && sudo apt install -y cmake g++ wget unzip
# Create build directory and switch into it
mkdir -p build && cd build
# Configure
cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.5.4/modules ../opencv-4.5.4
# Build
cmake --build . -j2
build完成后,继续执行:
sudo make install
opencv_version
opencv_version
出现4.5.4就算成功!
参考链接2还有后续步骤,主要是让pkg-config感知到opencv,这一步不做也行!见《一些注意点》第2点。
编译运行项目
代码在文末列出。
cmake ..
make -j2
./Rasterizer或./Rasterizer -r 85或./Rasterizer −r 85 rot_85.png
常见错误
1、运行项目时Failed to load module “canberra-gtk-module”
根据参考链接3,重新安装即可。
sudo apt-get install libcanberra-gtk-module
2、opencv build时CMake Error: failed to create symbolic link ‘…/…/lib/libopencv_core.so’: operation not permitted
这是因为包放在了挂载共享目录下。只能换一个非挂载文件夹,然后从头开始重新编译!
3、opencv build过程中卡死
我尝试了扩大磁盘空间+增加虚拟机内核数,都没用。后面增加了虚拟机的内存,成功!解决方案:在设置里增大虚拟机内存。
一些注意点
-
不建议使用jpg格式,除了图片大小变大没有任何好处。建议使用png格式。
-
4.5.x的版本不生成一个
openCV4.pc
文件,也是可以编译作业1的。sudo cp /usr/local/lib/pkgconfig/openCV4.pc /usr/lib/pkgconfig/
这些命令自然也不需要执行!不过这样pkg-config也就不能感知openCV了。 -
make -j2
时的警告:文件“CMakeFiles/Rasterizer.dir/depend.make”的修改时间在未来 0.66 秒后。我尝试了sudo systemctl restart systemd-timesyncd.service sudo timedatectl set-ntp true touch CMakeFiles/Rasterizer.dir/depend.make
以及重启虚拟机等多种方法,都无济于事。但是似乎不影响运行,暂时不管了!
代码
main.cpp
#include "Triangle.hpp"
#include "rasterizer.hpp"
#include <eigen3/Eigen/Eigen>
#include <iostream>
#include <vector>
#include <cctype>
#include <opencv2/opencv.hpp>
using namespace std;
template<class T>
T deg2rad (T v)
return v / 180.0 * M_PI;
Eigen::Matrix4f get_view_matrix (Eigen::Vector3f eye_pos)
Eigen::Matrix4f view = Eigen::Matrix4f::Identity();
Eigen::Matrix4f translate;
translate << 1, 0, 0, -eye_pos[0], \\
0, 1, 0, -eye_pos[1], \\
0, 0, 1, -eye_pos[2], \\
0, 0, 0, 1;
view = translate * view;
return view;
Eigen::Matrix4f get_model_matrix (float rotation_angle)
Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
// TODO: Implement this function
// Create the model matrix for rotating the triangle around the Z axis.
// Then return it.
Eigen::Matrix4f translate;
rotation_angle = deg2rad (rotation_angle);
translate << cos (rotation_angle), -sin (rotation_angle), 0.0, 0.0, \\
sin (rotation_angle), cos (rotation_angle), 0.0, 0.0, \\
0.0, 0.0, 1.0, 0.0, \\
0.0, 0.0, 0.0, 1.0;
model = translate * model;
return model;
Eigen::Matrix4f get_projection_matrix (float eye_fov, float aspect_ratio,
float zNear, float zFar)
// Students will implement this function
Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
// TODO: Implement this function
// Create the projection matrix for the given parameters.
// Then return it.
Eigen::Matrix4f m;
m << zNear, 0, 0, 0, \\
0, zNear, 0, 0, \\
0, 0, zNear + zFar, - (zNear * zFar), \\
0, 0, 1, 0;
float halve = deg2rad (eye_fov / 2);
float top = tan (halve) * zNear;
float bottom = -top;
float right = top * aspect_ratio;
float left = -right;
Eigen::Matrix4f n, p;
n << 2 / (right - left), 0, 0, 0, \\
0, 2 / (top - bottom), 0, 0, \\
0, 0, 2 / (zNear - zFar), 0, \\
0, 0, 0, 1;
p << 1, 0, 0, - (right + left) / 2, \\
0, 1, 0, - (top + bottom) / 2, \\
0, 0, 1, - (zFar + zNear) / 2, \\
0, 0, 0, 1;
projection = n * p * m;
return projection;
void support_c11_test()
vector<int> foo = []()
vector<int> tmp = 11, 45, 14, 19, 19, 810, 11;
return tmp;
();
for (auto x : foo) cout << x << ",";
cout << "support c11!" << endl;
int main (int argc, const char **argv)
float angle = 0;
bool command_line = false;
string filename = "output.png";
if (argc >= 3)
command_line = true;
angle = stof (argv[2]); // -r by default
if (argc >= 4)
filename = string (argv[3]);
rst::rasterizer r (700, 700);
Eigen::Vector3f eye_pos = 0, 0, 5;
vector<Eigen::Vector3f> pos2, 0, -2, 0, 2, -2, -2, 0, -2;
vector<Eigen::Vector3i> ind0, 1, 2;
auto pos_id = r.load_positions (pos);
auto ind_id = r.load_indices (ind);
int key = 0;
int frame_count = 0;
if (command_line)
r.clear (rst::Buffers::Color | rst::Buffers::Depth);
r.set_model (get_model_matrix (angle) );
r.set_view (get_view_matrix (eye_pos) );
r.set_projection (get_projection_matrix (45, 1, 0.1, 50) );
r.draw (pos_id, ind_id, rst::Primitive::Triangle);
cv::Mat image (700, 700, CV_32FC3, r.frame_buffer().data() );
image.convertTo (image, CV_8UC3, 1.0f);
cv::imwrite (filename, image);
return 0;
while (key != 27)
r.clear (rst::Buffers::Color | rst::Buffers::Depth);
r.set_model (get_model_matrix (angle) );
r.set_view (get_view_matrix (eye_pos) );
r.set_projection (get_projection_matrix (45, 1, 0.1, 50) );
r.draw (pos_id, ind_id, rst::Primitive::Triangle);
cv::Mat image (700, 700, CV_32FC3, r.frame_buffer().data() );
image.convertTo (image, CV_8UC3, 1.0f);
cv::imshow ("triangle_image", image);
key = cv::waitKey (10);
cout << "frame count: " << frame_count++ << endl;
if (tolower (key) == 'a')
angle += 10;
else if (tolower (key) == 'd')
angle -= 10;
support_c11_test();
return 0;
其他hpp和cpp文件都不用改。CMakeLists.txt也不用改。代码另开一篇blog解析。
opencv再写一个helloworld:https://blog.csdn.net/hans774882968/article/details/122883419
参考
- 官方文档:https://docs.opencv.org/4.5.4/d7/d9f/tutorial_linux_install.html
- https://www.bilibili.com/read/cv8168683
- https://blog.csdn.net/footrip/article/details/103639958
- https://blog.csdn.net/weixin_43629882/article/details/94384934
以上是关于GAMES101闫令琪图形学作业1(配置opencv4.5.4,并解决常见错误)的主要内容,如果未能解决你的问题,请参考以下文章