Linux下GDB除錯及OpenCV安裝及應用
- 前言
- 一、GDB除錯
- 啟動GDB
- GDB部分除錯命令
- GDB程式運行命令
- 常用的GDB命令
- 二、Ubuntu下的OpenCV
- 下載安裝OpenCV
- 圖片特效
- 視頻播放
- 疑難雜癥
- 視頻錄制及保存
- 三、總結
前言
除錯在編程中是必不可少的,那如何在Ubuntu中進行除錯呢,本文介紹了常用的GDB除錯命令;攝像頭在生活中的應用也是非常的廣泛,本文手把手教你OpenCV入門,
一、GDB除錯
首先我們編輯一個程式(用于除錯),下面是一個整形數反轉的程式:
#include<stdio.h>
void ShowR(int iNum) //整形數反轉子程式
{
while(iNum > 10) //INum大于10時,進入回圈
{
printf("%d",iNum%10);
iNum=iNum/10;
}
printf("%d",iNum);
}
int main(void)
{
int iNum;
printf("Please input a numbrt:");
scanf("%d",&iNum);
printf("After revert:");
ShowR(iNum);
}
啟動GDB
啟動GDB命令:
gcc -o ShowR -g ShowR.c //編譯
gdb ShowR //除錯
執行結果如下圖所示:

gcc -g 選項
-g選項可以利用操作西永的“原生格式(native format)”生成除錯資訊、GDB可以直接利用這個資訊,其他除錯器也可以使用這個除錯資訊,
注意:如果想用除錯器執行一個可執行檔案,在GCC編譯是必須加上 -g 選項
GDB部分除錯命令
GDB查看代碼命令
(gdb) l(ist) // ( 字母 l ) 從第一行開始列出原始碼,共列出10行,
執行結果如下圖所示:

若想繼續查看接下來的代碼,可以直接 空格 或繼續使用 l 命令,然后敲回車鍵,使用空格鍵查看接下來的命令如下圖所示:

也可以使用數字命令,直接顯示 某行 - 某行
(gdb) l 數字 ,數字
如下圖所示

GDB設定斷點命令
以行數設定斷點:
(gdb) b(reakpoint) 數字
數字為設定斷點的行數,示例如下圖所示,(提示設定斷點成功):

也可以通過函式名設定斷點:
(gdb) b 函式名
示例如下圖所示(提示第二個斷點設定成功):

可以通過命令查看斷點資訊:
info b(reakpoint)
示例如下圖所示:

GDB程式運行命令
GDB運行程式命令
(gdb) run
運行程式至斷點處,會停止運行,查看斷點行,然后輸入 c(ontinue) 之后,可以繼續運行,如下圖所示:
(gdb) c

在除錯程序中,如果需要查看引數型別,可以使用 whatis 命令,示例如下圖所示:
whatis 引數

在除錯程序中,如果需要查看引數的值,可以將引數值列印出來,使用 p(rint) 命令,示例如下圖所示:
(gdb) p(rint)

常用的GDB命令
二、Ubuntu下的OpenCV
下載安裝OpenCV
首先我們需要下載一個OpenCV的安裝包,可以在官網下載,可以在Linux系統中下載,不過這樣下載會比較慢,博主是直接下載到Windows系統中,然后復制到Linux系統中的,復制到Linux中的壓縮包如下圖所示,

然后進入到壓縮包所在路徑,對壓縮包解壓:
unzip opencv-3.4.1.zip
注意:版本有可能會不相同哦!
解壓縮之后,檔案中會有兩個檔案,一個是壓縮包,一個是解壓縮后的檔案夾,如下圖所示:

進入到opencv-3.4.1檔案夾中:
cd opencv-3.4.1
如下圖所示:

安裝依賴庫和cmake,如果提醒需要apt-get update,那就需要先進入root權限,再執行下面的命令:
sudo apt-get install cmake
執行結果如下圖所示:

再執行以下命令:
sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg.dev libtiff5.dev libswscale-dev libjasper-dev
執行結果如下圖所示:
溫馨提示:此程序也需要耐心等待,

安裝完成cmake之后,創建一個編譯檔案夾,然后進入檔案夾內進行配置:
mkdir hy_by_dir
cd hy_by_dir
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..

執行命令,開始漫長的編譯程序:
sudo make

漫長的等待后(博主等了大概兩小時):

執行命令:
sudo make install
到此,就完成了OpenCV的下載安裝作業,接下來就需要對OpenCV進行配置,輸入命令:
sudo gedit /etc/ld.so.conf.d/opencv.conf
執行命令后,會出現一個空白的檔案,此時需要在檔案中輸入:
/usr/local/lib
保存后回到輸命令的界面,執行命令:
sudo ldconfig
sudo gedit /etc/bash.bashrc
并在出現的檔案的末尾添加:
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
如下圖所示:

黑框部分為添加的代碼,
保存后退出,執行以下命令,并進行更新:
source /etc/bash.bashrc
sudo updatedb
歐耶,配置完成!接下來,我們試試做圖片的特效,
圖片特效
首先創立一個檔案夾,并到此檔案夾下,編輯一個特效影像的函式:
mkdir hytest
cd hytest
touch hyimage.cpp
nano hyimage.cpp
hyimage.cpp 的內容如下所示:
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
CvPoint center;
double scale = -3;
IplImage* image = cvLoadImage("iu.jpg"); //注意對應影像的名稱及后綴
argc == 2? cvLoadImage(argv[1]) : 0;
cvShowImage("Image", image);
if (!image) return -1; center = cvPoint(image->width / 2, image->heigh$
for (int i = 0;i<image->height;i++)
for (int j = 0;j<image->width;j++) {
double dx = (double)(j - center.x) / center.x;
double dy = (double)(i - center.y) / center.y;
double weight = exp((dx*dx + dy*dy)*scale);
uchar* ptr = &CV_IMAGE_ELEM(image, uchar, i, j * 3);
ptr[0] = cvRound(ptr[0] * weight);
ptr[1] = cvRound(ptr[1] * weight);
ptr[2] = cvRound(ptr[2] * weight);
}
Mat src;Mat dst;
src = cvarrToMat(image);
cv::imwrite("hyimage.png", src); //生成影像的名稱及后綴
cvNamedWindow("hyimage",1);
imshow("hyimage", src);
cvWaitKey();
return 0;
}
執行命令,將.cpp檔案生成可執行.exe檔案(如果 gcc 不成功,可以換成 g++ 試試):
g++ hyimage.cpp -o hyimage `pkg-config --cflags --libs opencv`
執行結果如下圖所示:

將影像從Windows系統復制到Linux系統中:

注意更改影像的名稱哦!程式里面的影像名稱要與檔案夾中影像名稱一致,
運行可執行檔案:
./hyimage
執行結果如下圖所示:

左邊為原始影像,右邊為特效后的影像;紅色框為原始影像檔案,黃色框為生成的影像檔案,影像特效完成!
注意:
① 影像所在位置要與.cpp的位置在一個檔案夾下,不然編譯可能會出錯;
② 也可以將 IplImage* image = cvLoadImage(“iu.jpg”); 改為絕對路徑,
視頻播放
依然在我們創立的檔案夾下面,創建一個 .cpp 的檔案,檔案內容如下:
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
VideoCapture capture("Clouds.mp4");
while(1)
{
Mat frame;
capture >> frame;
imshow("讀取視頻幀",frame);
waitKey(30);
}
system("pause");
return 0;
}
再將一個視頻添加到該目錄下,可以直接在Windows系統中復制到Linux系統中,播放的視頻支持.mp4和.avi格式:

注意:第五行的函式引數為視頻名稱及后綴,保證與檔案夾中的視頻名稱及后綴對應,
如果你的視頻檔案和創建的.cpp檔案不再同一目錄下,需要在第五行函式引數中加上絕對路徑,
視頻檔案添加好了,就可以試一下能否播放出視頻,雙擊視頻,如果能夠播放出,則不需要一下操作;如果不能播放出,則按照系統提示下載插件即可,
此時,如果你直接編譯運行程式,就會出現如下錯誤:

原因是你沒有將你的攝像頭設定在Ubuntu系統下,此時,你需要在Windows系統下運行 Win+R,然后執行陳述句 services.msc :

查看此選項是否啟動,若沒啟動,則點擊啟動:

將虛擬機設定中的 USB 兼容性換成 USB 3.0 :

點擊虛擬機,將攝像頭連接到虛擬機:

溫馨提示:如果換成兼容性換成 USB 3.0還是不成功,就換成 USB 2.0 或者 USB 1.1試試,總會有一款是兼容的,
如何查看自己的攝像頭是否能夠啟用了?輸入命令cheese如果有影像顯示,則表明攝像頭已經在虛擬機中啟用,示例如下圖所示:

此時就可以編譯,運行程式了:
g++ hyvideo.cpp -o hyvideo `pkg-config --cflags --libs opencv`
./hyvideo
運行結果如下圖所示:

疑難雜癥
①如果要求打開你硬碟上一個視頻檔案來播放,請問VideoCapture capture(0)行代碼如何修改?
修改為自己存盤影像檔案的目錄及名稱和后綴;若已在與.cpp相同的檔案夾下,則只需要添加名稱和后綴引數,
②在while回圈中,Mat是一個什么資料結構? 為什么一定要加一句waitKey延時代碼,洗掉它行不行?
Mat本質上是由兩個資料部分組成的類:(包含資訊有矩陣的大小,用于存盤的方法,矩陣存盤的地址等)的矩陣頭和一個指標,指向包含了像素值的矩陣(可根據選用于存盤的方法采用任何維度存盤資料),
Mat的第一件事是你不再需要手動分配其大小并且當你不需要它的時候,你不再需要手動釋放它(自動記憶體管理),
加了waitKey延時代碼后,才能播放視頻;如果洗掉延時代碼,將不能觀察到視頻播放,
特殊:當waitKey的引數為0時,即waitKey(0),此時程式會無限制等待用戶按下按鍵,
③此代碼會在while回圈中一直運行,你如果試圖用滑鼠關閉影像顯示視窗,會發現始終關不掉,需要用鍵盤Ctrl+C 強制中斷程式,非常不友好,如何改進?
在回圈代碼中加入條件陳述句:
if ( !cvGetWindowHandle ( " 視窗名字 " ) )
{
break;
}
此時就可以直接點擊左上方的“×”號,直接結束程勛運行,
視頻錄制及保存
這里還有一種升級版代碼,可以錄制視頻,并保存到本地檔案夾中,程式示例如下:
#include<iostream>
#include <opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
//打開電腦攝像頭
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error" << endl;
waitKey(0);
return 0;
}
//獲得cap的解析度
int w = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_WIDTH));
int h = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
Size videoSize(w, h);
VideoWriter writer("RecordVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25, videoSize);
Mat frame;
int key;//記錄鍵盤按鍵
char startOrStop = 1;//0 開始錄制視頻; 1 結束錄制視頻
char flag = 0;//正在錄制標志 0-不在錄制; 1-正在錄制
while (1)
{
cap >> frame;
key = waitKey(100);
if (key == 32)//按下空格開始錄制、暫停錄制 可以來回切換
{
startOrStop = 1 - startOrStop;
if (startOrStop == 0)
{
flag = 1;
}
}
if (key == 27)//按下ESC退出整個程式,保存視頻檔案到磁盤
{
break;
}
if (startOrStop == 0 && flag==1)
{
writer << frame;
cout << "recording" << endl;
}
else if (startOrStop == 1)
{
flag = 0;
cout << "end recording" << endl;
}
imshow("picture", frame);
}
cap.release();
writer.release();
destroyAllWindows();
}
按下空格鍵錄制視頻和暫停錄制:

錄制的視頻將存盤在該目錄下:

紅色框為錄制保存的視頻,
三、總結
在Linux中,我們可以使用GDB來進行對程式的除錯;此次學習OpenCV之后,對其有了初步的了解,OpenCV的海洋很深,等待著我們遨游,
加油吧,讀書人!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/198529.html
標籤:其他
