我们知道Windows
下有类似UltraISO
的这样的软件可以用来编辑ISO
文件,可引导ISO
也没有问题。近来在Linux
下玩的比较多,正好要改个ISO
,于是就开始找Linux
下有没有类似的软件。
Ubuntu
软件中心里有一款叫ISOMaster
的软件,可以创建和修改ISO
文件。
我们知道Windows
下有类似UltraISO
的这样的软件可以用来编辑ISO
文件,可引导ISO
也没有问题。近来在Linux
下玩的比较多,正好要改个ISO
,于是就开始找Linux
下有没有类似的软件。
Ubuntu
软件中心里有一款叫ISOMaster
的软件,可以创建和修改ISO
文件。
在Ubuntu
系统上进行如下配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ sudo apt-get update $ sudo apt-get upgrade $ sudo apt-get install python-dev $ sudo apt-get install python-pip $ sudo pip install --upgrade pip $ sudo pip install --upgrade urllib3 $ sudo pip install numpy $ sudo pip install matplotlib |
之后执行如下测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import sys import numpy as np import matplotlib.pyplot as plt plt.ion() (fig, axis) = plt.subplots() bar_plot = axis.barh(0, 8,linewidth = 0) bar_plot.color= '#ffff00' for i in range(20): axis.set_xlim(xmax = max(i + 1, 10)) plt.draw() if sys.version_info < (3, 0): raw_input("Press Enter to continue...") else: input("Press Enter to continue...") |
上面的测试代码在Ubuntu 14.04.5
版本上是可以正常执行的,对应的matplotlib
的版本是matplotlib 1.3.1
,但是放到Ubuntu 16.04.2
系统上则是无法正常显示的,对应的matplotlib
的版本是matplotlib 1.5.1
。
造成这个问题的原因在于matplotlib.pyplot.draw()
,这个函数行为的改变,早期这个函数是同步更新界面的,后来的版本却变成了空闲异步更新界面,只有当matplotlib.pyplot.pause(interval)
被调用的时候才会刷新界面。
所以只需要上面的代码修改成如下即可在不同版本之间兼容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import sys import numpy as np import matplotlib.pyplot as plt plt.ion() (fig, axis) = plt.subplots() bar_plot = axis.barh(0, 8,linewidth = 0) bar_plot.color= '#ffff00' for i in range(20): axis.set_xlim(xmax = max(i + 1, 10)) plt.draw() plt.pause(0.00001) if sys.version_info < (3, 0): raw_input("Press Enter to continue...") else: input("Press Enter to continue...") |
注意,我们在matplotlib.pyplot.draw()
调用后面增加了matplotlib.pyplot.pause(interval)
的调用。
貌似调用fig.canvas.flush_events()
更合适?
查看matplotlib
的版本使用如下代码:
1 2 |
import matplotlib as mpl print mpl.__version__ |
在Ubuntu 16.04
上测试OpenCV 3.2
,遇到一个在子线程中更新图像,而界面不刷新的问题。
1 |
$ sudo apt-get install libopencv-dev |
编译执行如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <pthread.h> #include <opencv/cv.h> #include <opencv/highgui.h> #include <stdio.h> #include <stdlib.h> void* imshowWorker(void*){ for(int i = 0;i < 100;i++){ char str[10+1]; snprintf(str, 10,"%d",i); cv::Mat img = cv::Mat::zeros( 100, 100, CV_8UC3 ); cv::putText(img,(char*)str,cv::Point( 50, 50 ),cv::FONT_HERSHEY_SIMPLEX,1,cv::Scalar( 255, 0, 0 )); cv::imshow("Number View", img ); if(i > 90){ i = 0; } } } int main(void){ cv::namedWindow("Number View"); pthread_t id; pthread_create(&id,NULL,imshowWorker,NULL); getchar(); return (0); } |
1 |
$ g++ opencv_imshow.cpp -I `pkg-config --libs opencv` -lpthread -o opencv_imshow |
可以看到,上面的代码执行之后,界面并没有出现,即使出现也没有刷新。
这个问题是由于界面更新必须在主线程中执行,需要手工通知主线程。
修改后的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <pthread.h> #include <opencv/cv.h> #include <opencv/highgui.h> #include <stdio.h> #include <stdlib.h> void* imshowWorker(void*){ for(int i = 0;i < 100;i++){ char str[10+1]; snprintf(str, 10,"%d",i); cv::Mat img = cv::Mat::zeros( 100, 100, CV_8UC3 ); cv::putText(img,(char*)str,cv::Point( 50, 50 ),cv::FONT_HERSHEY_SIMPLEX,1,cv::Scalar( 255, 0, 0 )); cv::imshow("Number View", img ); cv::waitKey(30); if(i > 90){ i = 0; } } } int main(void){ cv::namedWindow("Number View"); pthread_t id; pthread_create(&id,NULL,imshowWorker,NULL); getchar(); return (0); } |
也就是每次更新图片后手工调用代码
1 |
cv::waitKey(30); |
这个等候时间,只要大于0
即可,比如:
1 |
cv::waitKey(1); |
最近在更新Ubuntu 16.04
系统的时候,发现总是在安装Adobe Flash
更新的时候失败,提示如下信息:
1 2 3 4 5 6 7 8 9 |
正在处理用于 update-notifier-common (3.168.5) 的触发器 ... flashplugin-installer: processing... flashplugin-installer: downloading http://archive.canonical.com/pool/partner/a/adobe-flashplugin/adobe-flashplugin_20170912.1.orig.tar.gz 获取:1 http://archive.canonical.com/pool/partner/a/adobe-flashplugin/adobe-flashplugin_20170912.1.orig.tar.gz [30.4 MB] 37% [1 /var/lib/update-notifier/package-data-downloads/partial/adobe-flashplugi 已下载 30.4 MB,耗时 10分 11秒 (49.8 kB/s) W: 文件'/var/lib/update-notifier/package-data-downloads/partial/adobe-flashplugin_20170912.1.orig.tar.gz'无法被用户'_apt'访问,无法降低权限以进行下载。 - pkgAcquire::Run (13: 权限不够) E: 下载失败 |
如果系统语言是英文的,可能看到下面的信息:
1 |
W: Can't drop privileges for downloading as file '/var/lib/update-notifier/package-data-downloads/partial/adobe-flashplugin_20170912.1.orig.tar.gz' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied) |
解决方法如下:
1 2 3 4 5 6 7 |
$ sudo chown -R _apt:root /var/lib/update-notifier/package-data-downloads/partial/ $ sudo rm /var/lib/update-notifier/package-data-downloads/partial/*.FAILED $ sudo apt install --reinstall update-notifier-common $ sudo apt-get install --reinstall flashplugin-installer |
这样,就可以正常安装更新了。
我想使用一些在旧的GCC
版本中不可用的GCC
警告开关(例如-Wtype-limits
)。
有没有一个简单的方法来检查GCC
版本?
我不会说容易,但是可以使用GNU make
的SHELL
函数来执行gcc --version
命令,然后使用ifeq
条件表达式来检查版本号,并适当地设置CFLAGS
变量。
以下是一个简单的MakeFile
示例:
1 2 3 4 5 6 7 8 9 10 |
CC = gcc GCCVERSION = $(shell gcc --version | grep ^gcc | sed 's/^.* //g') CFLAGS = -g ifeq "$(GCCVERSION)" "4.4.3" CFLAGS += -Wtype-limits endif all: $(CC) $(CFLAGS) prog.c -o prog |
注意:不存在ifgt
语法。但是可以使用expr
命令进行比较。
例子如下:
1 2 3 4 5 6 7 8 9 10 |
CC = gcc GCCVERSIONGTEQ4 := $(shell expr `gcc -dumpversion | cut -f1 -d.` \>= 4) CFLAGS = -g ifeq "$(GCCVERSIONGTEQ4)" "1" CFLAGS += -Wtype-limits endif all: $(CC) $(CFLAGS) prog.c -o prog |
要将完整的3
部分GCC
版本(不仅第一位数字)转换成数字格式,适合比较(例如40701
)使用
1 |
gcc -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$/&00/' |
其中解决了任何版本部分中双数字版本号的可能性,以及gcc -dumpversion
输出内容缺少3
个部分的可能性(在一些较早的GCC
版本中存在这种情况)。
所以要测试MakeFile
中的版本,使用(注意$$
里面的最后一个sed
命令)
1 2 3 4 |
GCC_GTEQ_472 := $(shell expr `gcc -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/'` \>= 40702) ifeq "$(GCC_GTEQ_472)" "1" ... endif |
我刚刚遇到这个问题,我需要测试GCC
的前两位数字,想要一个比上面sed
过滤字符串更复杂的操作。我使用bc
进行比较,因为它支持浮点数(expr
将非整数(non-integers
)都视为字符串):
1 2 3 4 |
GCC_VER_GTE44 := $(shell echo `gcc -dumpversion | cut -f1-2 -d.` \>= 4.4 | bc ) ifeq ($(GCC_VER_GTE44),1) ... endif |
如果在GCC 4.9
之后发布了GCC 4.10
,那么用sed
处理是必要的:
1 2 3 4 |
GCC_VER_GTE44 := $(shell echo `gcc -dumpversion | cut -f1-2 -d.` \>= 4.4 | sed -e 's/\./*100+/g' | bc ) ifeq ($(GCC_VER_GTE44),1) ... endif |
对于Ubuntu 14.04.5
系统上的安装操作,请参考Ubuntu 14.04.5系统上OpenPTrack V1版本安装配置(Kinect V2)
下面是我自己fork
出来修改后的代码在Ubuntu 16.04.3
系统上的安装操作
要求机器上必须有CUDA 8.0/9.0
支持的显卡才可以。
1 2 3 |
$ sudo apt-get install git -y $ cd ~ $ git clone https://github.com/wangqiang1588/open_ptrack_org.git open_ptrack |
1 2 3 4 5 6 |
$ cd open_ptrack/scripts $ chmod +x *.sh $ ./ros_install.sh $ source /opt/ros/kinetic/setup.bash $ ./ros_configure.sh |
OpenPTrack
1 2 3 |
$ sudo apt-get install libdrm-dev $ ./openptrack_install.sh |
OpenPTrack
目录
1 |
$ ln -s ~/workspace/ros/catkin/src/open_ptrack ~/open_ptrack |
Kinect V2
驱动程序安装检查当前用户目录下的.bashrc
文件,注释掉如下内容:
1 |
export KINECT_DRIVER=openni |
然后执行如下命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# Nvidia Jetson TX1/TX2 不要安装这个 $ sudo apt-get install nvidia-375-dev # Nvidia Jetson TX1/TX2不支持OpenCL,因此编译的时候,不要安装ocl-icd-opencl-dev $ sudo apt-get install ocl-icd-opencl-dev $ sudo apt-get install m4 $ sudo apt-get install automake $ sudo apt-get install libjpeg-dev $ sudo ln -s -f /usr/lib/`uname -m`-linux-gnu/libturbojpeg.so.0 /usr/lib/`uname -m`-linux-gnu/libturbojpeg.so $ sudo apt-get install libglewmx-dev $ sudo apt-get install libudev-dev $ sudo ln -s -f /lib/`uname -m`-linux-gnu/libudev.so.1 /lib/`uname -m`-linux-gnu/libudev.so $ cd ~/workspace/ros/catkin/src $ source ~/.profile $ roscd open_ptrack/../scripts $ chmod +x kinect2_install.sh $ ./kinect2_install.sh |
6.重新编译代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
UBUNTU_VERSION=`lsb_release -c -s` ROS_DISTRO=hydro if [ $UBUNTU_VERSION = trusty ] || [ $UBUNTU_VERSION = saucy ] ; then ROS_DISTRO=indigo elif [ $UBUNTU_VERSION = xenial ] ; then ROS_DISTRO=kinetic fi GCC_VERSION=`gcc -dumpversion | cut -f1 -d.` source /opt/ros/$ROS_DISTRO/setup.bash cd ~/workspace/ros/catkin catkin_make --pkg calibration_msgs catkin_make --pkg opt_msgs #GCC 5 bug out of memory if [ $GCC_VERSION > 4 ] ; then catkin_make --force-cmake -j 1 else catkin_make --force-cmake fi |
执行如下命令:
1 |
$ roscore |
检查当前用户目录下的.bashrc
文件,然后注释掉如下内容:
1 |
export KINECT_DRIVER=openni |
上面语句如不注释,会导致程序启动时候的崩溃。
新建一个Shell
,执行如下命令
1 2 |
$ cd ~/workspace/ros/catkin/devel/lib/kinect2_bridge $ sudo ./kinect2_bridge |
执行此步的时候如果提示找不到Kinect
设备,请重启一下系统再试试。
可能需要重新插拔一下Kinect
的USB
数据线,然后执行如下命令
1 |
$ roslaunch kinect2_bridge kinect2_bridge.launch |
执行之后,等待十几秒,然后Ctrl+C
中断执行。
执行完成后,执行
1 |
$ roslaunch tracking detection_and_tracking_kinect2.launch |
之后,会弹出三个界面出来。
参考Kinect V2在Ubuntu 14.04系统上的驱动配置与安装在一个全新安装的Ubuntu 14.04
系统中配置完成相关的驱动及其依赖。
Kinect V2
深度图与彩色图融合的方式,简单粗暴,由于深度图像是512*424
大小,因此,直接把彩色图像缩放成对应的512*424
,然后像素点一一对应。至于原始大小的彩色图像,那么就是一片像素对应同一个深度即可。
注意,这个方式只适合Kinect V2
,可以理解成Kinect V2
的设计就是这样的,两个设备出厂的时候就校准为这样的输出。
具体的转换代码参考registration.cpp,Registration.cpp,建议直接调用驱动层提供的功能来实现,这样的话,一系列的参数设置可以同步,否则上层每次修改了分辨率等参数的时候,要自己手工修改这些数据。
Python
深度图与彩色图融合的例子如下:
Debian 9
(代号为Stretch
)已经正式发布,可以开始尝鲜Debian 9
了。
1. 更新Debian Jessie
到最新版
1 2 3 4 5 6 7 |
$ su $ apt-get update $ apt-get upgrade $ apt-get dist-upgrade |
2. 将软件源改为Stretch
安装源
1 2 3 4 5 6 7 8 |
$ su $ sed -i 's/jessie/stretch/g' /etc/apt/sources.list # 替换成国内镜像源(清华大学) $ sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list $ sed -i 's/security.debian.org/mirrors.tuna.tsinghua.edu.cn\/debian-security/g' /etc/apt/sources.list |
3. 升级系统版本
1 2 3 4 5 |
$ su $ apt-get update $ apt-get dist-upgrade |
4. 重启
1 2 3 |
$ su $ reboot |
以下的操作是在一个全新安装的Ubuntu 14.04
系统上进行的,目前已知在安装了ROS
的系统上并且已经安装过ROS
版本的Kinect V2
驱动的,可能需要先移除以前安装的面向ROS
编译的Kinect V2
驱动才行。
首先是安装配置驱动程序以及运行依赖库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ sudo apt-get update $ sudo apt-get upgrade $ sudo apt-get dist-upgrade $ sudo apt-get install python-opencv $ sudo apt-get install python-dev $ sudo apt-get install python-pip $ sudo pip install openni $ sudo apt-get install git |
参照libfreenect2 install linux的说明安装驱动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
$ cd ~ $ git clone https://github.com/OpenKinect/libfreenect2.git $ cd libfreenect2 $ cd depends; ./download_debs_trusty.sh $ sudo dpkg -i debs/libusb*deb $ sudo apt-get install build-essential cmake pkg-config #如果没有配置ROS源,则使用这个源,否则不需要此步骤 $ sudo apt-add-repository ppa:deb-rob/ros-trusty && sudo apt-get update $ sudo apt-get install libopenni2-dev $ sudo apt-get install libjpeg-dev $ sudo apt-get install libturbojpeg $ sudo apt-get install libgl1-mesa-dev $ sudo apt-get install ocl-icd-opencl-dev #如果要启用CUDA的支持,只能是从nvidia官网下载安装最新版本才行,apt安装的版本会缺少 “ helper_math.h ” # $ wget https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1404-8-0-local-ga2_8.0.61-1_amd64-deb # $ sudo apt-get update # $ sudo apt-get install cuda $ cd .. $ git clean -xfd $ mkdir build && cd build ##如果在安装过ROS的系统上执行,并且已经通过ROS安装过libfreenect2驱动,可能下面的要调整成“cmake .. -DCMAKE_INSTALL_PREFIX=/usr/” 才能成功覆盖已经安装过的文件 $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local/ $ make $ sudo make install |
安装Python
扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$ cd ~ $ sudo pip install cython $ sudo pip install numpy $ git clone https://github.com/remexre/pyfreenect2.git $ cd pyfreenect2 $ sudo python setup.py install $ sudo apt-get install gfortran $ sudo apt-get install libopenblas-dev $ sudo apt-get install liblapack-dev $ sudo pip install scipy |
Python
例子如下:
1 2 3 |
$ cd ~/pyfreenect2 $ python test.py |
注意,如果编译的时候出现如下错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
[ 5%] Building NVCC (Device) object CMakeFiles/cuda_compile.dir/src/./cuda_compile_generated_cuda_kde_depth_packet_processor.cu.o nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning). nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning). ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1346): error: name followed by "::" must be a class or namespace name ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1346): error: explicit type is missing ("int" assumed) /home/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1346): error: expected a "{" ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1349): warning: missing return statement at end of non-void function "libfreenect2::CudaKdeDepthPacketProcessor" ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1351): error: name followed by "::" must be a class or namespace name ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1353): error: identifier "impl_" is undefined /home/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1356): error: name followed by "::" must be a class or namespace name ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1358): error: a nonstatic member reference must be relative to a specific object ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1360): error: identifier "impl_" is undefined ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1363): error: name followed by "::" must be a class or namespace name ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1365): error: identifier "impl_" is undefined ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1369): error: name followed by "::" must be a class or namespace name ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1371): error: identifier "impl_" is undefined ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1378): error: name followed by "::" must be a class or namespace name ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1380): error: identifier "impl_" is undefined ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1383): error: name followed by "::" must be a class or namespace name ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1385): error: identifier "impl_" is undefined ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1388): error: name followed by "::" must be a class or namespace name ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1390): error: identifier "listener_" is undefined ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1393): error: identifier "impl_" is undefined ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1415): error: name followed by "::" must be a class or namespace name ~/libfreenect2/src/cuda_kde_depth_packet_processor.cu(1417): error: identifier "impl_" is undefined ~/longsky/libfreenect2/src/cuda_kde_depth_packet_processor.cu(413): warning: function "calculatePhaseUnwrappingVarDirect" was declared but never referenced 21 errors detected in the compilation of "/tmp/tmpxft_00004ae7_00000000-7_cuda_kde_depth_packet_processor.cpp1.ii". CMake Error at cuda_compile_generated_cuda_kde_depth_packet_processor.cu.o.cmake:264 (message): Error generating file ~/libfreenect2/build/CMakeFiles/cuda_compile.dir/src/./cuda_compile_generated_cuda_kde_depth_packet_processor.cu.o make[2]: *** [CMakeFiles/cuda_compile.dir/src/./cuda_compile_generated_cuda_kde_depth_packet_processor.cu.o] Error 1 make[1]: *** [CMakeFiles/freenect2.dir/all] Error 2 make: *** [all] Error 2 |
则该现象出现的原因是首先参照
1 |
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/freenect2 |
进行了编译,并且编译的时候是没有开启CUDA
支持的。
然后执行了
1 |
$ make install |
因此在~/libfreenect2/include/libfreenect2/
下面已经生成了config.h
,export.h
这两个文件。
然后又按照我们这里的
1 |
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local/ |
重新编译,并且这次开启了CUDA
支持,导致GCC
在编译的时候使用了我们在~/libfreenect2/build/libfreenect2/
下面生成的config.h
,export.h
这两个文件,而NVCC
却使用了~/libfreenect2/include/libfreenect2/
下面的config.h
,export.h
进行编译,导致上面的错误发生。
因此删除全部的临时文件,然后再次重新编译即可。
参照Ubuntu 14.04.5系统上OpenPTrack V1版本安装配置(Kinect V2)配置安装完成后,是单台机器的方式。
如果场地比较大,则需要部署多个Kinect V2
。由于每台Kinect V2
看到同一个人的视角不同,因此需要校准,才能进行合并。
下面,我们用两台PC
+两个Kinect V2
(每台机器上连接一个Kinect V2
)来演示一下如何校准的操作。