s1081050 作業1

圖像旋轉 (Image Rotation)

目錄

作業說明

撰寫一個程式將一張圖像的(a)整張圖像,(b)中心內切圓區域,旋轉一個角度(逆時針旋
轉 0 度至 359 度):利用一個滑動條(trackbar)控制旋轉角度。

開發環境

$ uname -srvmio
Linux 5.19.0-35-generic #36~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb 17 15:17:25 UTC 2 x86_64 x86_64 GNU/Linux
$ gcc --version
gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
$ pkg-config --modversion opencv4
4.5.4

程式碼說明

(a)整張圖片旋轉

宣告與初始化變數

// include opencv 與 stdio library #include "opencv2/highgui.hpp" #include "opencv2/imgcodecs.hpp" #include <opencv2/opencv.hpp> #include <stdio.h> // 定義GUI視窗名稱、滑動條名稱與最大值 #define WINDOW_TITLE "Rotated image" #define SLIDER_MAX 359 #define TRACK_BAR_NAME "Degree" // 使用 cv namespace using namespace cv; //設定全域變數 src 用來儲存圖片 Mat src;

函式宣告

// 宣告一個 function 當 trackbar onchange 時執行 static void on_trackbar(int, void *) { // 取得Trackbar的位置(Position) double degree = getTrackbarPos(TRACK_BAR_NAME, WINDOW_TITLE); // 宣告一個物件用於儲存輸出矩陣 Mat output; /* 宣告一個轉置矩陣 * 利用 getRotationMatrix2D 可以產生一個旋轉矩陣 * 第一個參數為旋轉中心,以圖片的中心為旋轉點 * 第二個參數為旋轉角度 * 第三個參數為縮放比例 */ Mat rotation = getRotationMatrix2D(Point2f(src.cols / 2, src.rows / 2), degree, 1); // 矩陣重新映射至 output warpAffine(src, output, rotation, src.size()); // 顯示 output 之影像 imshow(WINDOW_TITLE, output); }

旋轉矩陣運作原理

M=[αβ(1α)center.xβcenter.yβαβcenter.x+(1α)center.y]

α=scalecos(angle)
β=scalesin(angle)

介面控制

// 透過 argc argv 去接收圖片路徑 int main(int argc, char **argv) { // 當參數不為 2 時表示路徑格是錯誤 if (argc != 2) { printf("usage: DisplayImage.out <Image_Path>\n"); return -1; } // 讀入路徑圖片 src = imread(argv[1], IMREAD_COLOR); if (src.empty()) { printf("%s", "Error loading image \n"); return -1; } // 命名新的視窗 namedWindow(WINDOW_TITLE, WINDOW_AUTOSIZE); // 建立 trackbar createTrackbar(TRACK_BAR_NAME, WINDOW_TITLE, nullptr, SLIDER_MAX, on_trackbar); // 設定 trackbar 位置 setTrackbarPos(TRACK_BAR_NAME, WINDOW_TITLE, 0); // 初始化位置 on_trackbar(0, 0); waitKey(0); return 0; }

(b)圖片中心旋轉

#include "opencv2/highgui.hpp" #include "opencv2/imgcodecs.hpp" #include <opencv2/opencv.hpp> #include <stdio.h> #define WINDOW_TITLE "Rotated image center" #define SLIDER_MAX 359 #define TRACK_BAR_NAME "Degree" #define CIRCLE_SCALE 100 using namespace cv; Mat src; static void on_trackbar(int, void *) { double degree = getTrackbarPos(TRACK_BAR_NAME, WINDOW_TITLE); Mat mask = Mat::zeros(src.size(), src.type()); Mat rev_mask; Mat output, middle; Point2f center(src.cols / 2, src.rows / 2); // 建立一個圓形圖案,並儲存至mask作為遮罩 circle(mask, center, CIRCLE_SCALE, Scalar(255, 255, 255), FILLED); //原圖透過遮罩後存入middle src.copyTo(middle, mask); //建立一個反向遮罩 bitwise_not(mask, rev_mask); //原圖透過反向遮罩存入rev_mask src.copyTo(output, rev_mask); /* 現在已經將原圖拆為兩個部分 * 1.內部圓形 * 2.外部框架 */ // 旋轉中間圓形部分 Mat rotation = getRotationMatrix2D(center, degree, 1); warpAffine(middle, middle, rotation, middle.size()); // 輸出旋轉後的內部圓形與外部框架之合併圖 imshow(WINDOW_TITLE, middle | output); } int main(int argc, char **argv) { // get image path from command line if (argc != 2) { printf("usage: DisplayImage.out <Image_Path>\n"); return -1; } // load image from path src = imread(argv[1], IMREAD_COLOR); if (src.empty()) { printf("%s", "Error loading image \n"); return -1; } // create window namedWindow(WINDOW_TITLE, WINDOW_AUTOSIZE); createTrackbar(TRACK_BAR_NAME, WINDOW_TITLE, nullptr, SLIDER_MAX, on_trackbar); setTrackbarPos(TRACK_BAR_NAME, WINDOW_TITLE, 0); // initial window on_trackbar(0, 0); waitKey(0); return 0; }

程式展示

編譯

進入資料夾

cmake . make


執行

a

./HW1a yzu.bmp

初始化 旋轉30 旋轉345

b

./HW1b yzu.bmp

初始化 旋轉43 旋轉270

參考資料

cv::getRotationMatrix2D
cv:wrapAffine
cv Sample(需要從source編譯)

tags: CS362 s1081050 HW1

留言

這個網誌中的熱門文章

rzwang Homework #1

s1093350 Homework #2

s1091537 Homework #1