1. 程式人生 > 實用技巧 >[環境配置]macOS Homebrew安裝OpenCV以及使用

[環境配置]macOS Homebrew安裝OpenCV以及使用

系統資訊

  • macOS Catalina 10.15.7

  • Homebrew 2.5.11

  • CMake 3.19.0

部署

  • 開啟終端,輸入brew install cmake安裝cmake的命令列工具。

  • 輸入brew install opencv進行安裝,Homebrew會自動將OpenCV的依賴部署到系統目錄中。

使用

選擇一個空目錄,用文字編輯器新建一個CMakeLists.txt,複製以下內容並儲存

cmake_minimum_required(VERSION 3.10)
project(Test)

#CMake通過此命令自動尋找OpenCV的依賴
find_package(OpenCV REQUIRED)

set(CMAKE_CXX_STANDARD 17)

include_directories(/usr/local/include)

add_executable(Test make.cpp)
target_link_libraries(Test ${OpenCV_LIBRARIES})

在其同級目錄下新建main.cpp,並複製、儲存以下測試程式碼:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <ctime>

#include <eigen3/Eigen/Eigen>
#include <opencv2/opencv.hpp>

#define DEBUG
#define CALCU_TIME(start, end) \
    std::cout << "Spend Time::" <<(double)(end - start) / CLOCKS_PER_SEC << "s" << std::endl;
#define SHOW_POINT(point) \
    std::cout << "(" << point.x() << ", " << point.y() << ")" << std::endl;

static const int WIDTH  = 700;
static const int HEIGHT = 700;

std::vector<Eigen::Vector3f> frameBuffer;

void putPixel(const Eigen::Vector2i& point) {
    int index = (HEIGHT - point.y())*WIDTH + point.x();
    frameBuffer[index] = Eigen::Vector3f(255.0f, 255.0f, 255.0f);
}

void draw() {
    int key = -1;
    while(key != 27) {
        cv::Mat image(WIDTH, HEIGHT, CV_32FC3, frameBuffer.data());
        image.convertTo(image, CV_8UC3, 1.0f);
        cv::imshow("Image", image);

        key = cv::waitKey(10);
    }
}

void Bresenham(const Eigen::Vector2f& begin, const Eigen::Vector2f& end)
{
    float x0 = begin.x();
    float y0 = begin.y();
    float x1 = end.x();
    float y1 = end.y();

    // 確保計算方向為正向
    if(x0 > x1) {
        std::swap(x0, x1);
        std::swap(y0, y1);
    }

    int dX = (int)fabs(x1 - x0);
    int dY = (int)fabs(y1 - y0);
    int delta = dX - 2 * dY;

    int dStepUp = 2 * (dX - dY);
    int dStepDown = -2 * dY;

    int x = (int)x0, y = (int)y0;

    for(int i = x; i != (int)x1; i++) {
        putPixel(Eigen::Vector2i(i, y));
        SHOW_POINT(Eigen::Vector2i(i, y));
        if(delta < 0) {
            y += 1;
            delta += dStepUp;
        } else {
            delta += dStepDown;
        }
    }
}

void DDA(Eigen::Vector2f begin, Eigen::Vector2f end)
{
    float x0 = begin.x();
    float y0 = begin.y();
    float x1 = end.x();
    float y1 = end.y();

    float dx = fabs(x1 - x0);
    float dy = fabs(y1 - y0);

    // 選擇最大截距方向為步長方向
    float step = std::max(dx, dy);

    // 若step選擇的移動方向為x軸,則deltaX = dx / dx = 1,即預設在x方向進行步長為1的移動
    // 同理deltaY = 1
    float deltaX = dx / step;
    float deltaY = dy / step;

    float x = x0, y = y0;
    putPixel(Eigen::Vector2i(x, y));
    SHOW_POINT(Eigen::Vector2i(x, y));

    for(int i = 0 ; i < (int)step ; i++) {
        x += deltaX;
        y += deltaY;
        putPixel(Eigen::Vector2i(x, y));
        SHOW_POINT(Eigen::Vector2i(x, y));
    }
}

int main() {
    frameBuffer.resize(WIDTH * HEIGHT);
    std::fill(frameBuffer.begin(), frameBuffer.end(), Eigen::Vector3f{0, 0, 0});

    auto point = Eigen::Vector2f(700, 700);

    clock_t startTime, endTime;
    startTime = clock();

    //Bresenham(Eigen::Vector2f(0, 0), point);
    DDA(Eigen::Vector2f(0, 0), point);

    endTime = clock();
    CALCU_TIME(startTime, endTime);

    draw();

    return 0;
}

終端CD此目錄:

  • mkdir build命令建立一個目標生成資料夾

  • cd build進入目標生成資料夾

  • cmake ..cmake檢測上級目錄的CMakeLists.txt並在build目錄中生成makefile

  • make 開始編譯並生成二進位制檔案

  • ./Test執行

成功後會看到這個視窗,鍵盤按下ESC退出。

之後每次修改程式碼後就再在build目錄下使用一次make命令重新編譯。

值得一提的是,Jetbrains的CLion本身是通過CMake管理專案的,如果你有CLion可以直接開啟這個目錄(build的上級),一鍵執行,很方便。