macOS下opencv的安装。在CLion上配置使用OpenCV (C++)

安装opencv

  • brew的安装

    /usr/bin/ruby -e "$(curl -fsSL <https://raw.githubusercontent.com/Homebrew/install/master/install>)"
    
  • brew安装opencv

    brew install opencv
    
    cmake_minimum_required(VERSION 3.17)
    project(opencv)
    
    set(CMAKE_CXX_STANDARD 11)
    
    find_package(OpenCV REQUIRED)
    
    include_directories(${OpenCV_INCLUDE_DIRS})
    
    add_executable(opencv main.cpp) 
    
    target_link_libraries(opencv ${OpenCV_LIBS})
    
    cd "$(brew --repo)"
    git remote set-url origin <https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git>
    cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
    git remote set-url origin <https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git>
    cd 
    brew update
    
    brew update
    brew install opencv
    
    brew install libav
    
    cmake_minimum_required(VERSION 3.17)
    project(watermark_C__14)
    
    find_package(OpenCV)
    include_directories(${OpenCV_INCLUDE_DIRS})
    
    set(CMAKE_CXX_STANDARD 14)
    set(SOURCE_FILES main.cpp)
    
    add_executable(watermark_C__14 ${SOURCE_FILES})
    target_link_libraries(watermark_C__14 ${OpenCV_LIBS}) # 链接库
    
    /usr/local/Cellar/gcc
    
    preferences >> Build,execution,deployment >> toolchains >> GCC
    
     brew install opencv@3
    
    #include <iostream>
    #include <opencv2/opencv.hpp>       //调用 OpenCV 的库
    
    using namespace cv;
    
    int main()
    {
        Mat image;      // OpenCV 中图片格式为 Mat
    
        image = imread( "要显示的图片路径.png"); //读取图片
        if( image.empty() )             //检查是否读取成功
        {
            std::cout <<  "Could not open or find the image" << std::endl ;
            return -1;
        }
        imshow("demo",image);   //显示图片
    
        waitKey();
        return 0;
    }
    
    void test(){
        std::cout << CV_VERSION_MAJOR << CV_VERSION_MINOR << std::endl;
        std::cout << cv::getBuildInformation().c_str() << std::endl;
    }
    int main()
    {
        test();
    }
    
    #include <stdlib.h>
    
    #include <opencv2/core/utility.hpp>
    #include <opencv2/tracking.hpp>
    #include <opencv2/videoio.hpp>
    #include <opencv2/highgui.hpp>
    
    #include "opencv2/imgproc/types_c.h"
    
    using namespace cv;
    std::vector<cv::Mat> planes;
    cv::Mat complexImage;
    
    void shiftDFT(cv::Mat image)
    {
        image = image(Rect(0, 0, image.cols & -2, image.rows & -2));
        int cx = image.cols / 2;
        int cy = image.rows / 2;
    
        Mat q0 = Mat(image, Rect(0, 0, cx, cy));
        Mat q1 = Mat(image, Rect(cx, 0, cx, cy));
        Mat q2 = Mat(image, Rect(0, cy, cx, cy));
        Mat q3 = Mat(image, Rect(cx, cy, cx, cy));
    
        cv::Mat tmp = cv::Mat();
        q0.copyTo(tmp);
        q3.copyTo(q0);
        tmp.copyTo(q3);
    
        q1.copyTo(tmp);
        q2.copyTo(q1);
        tmp.copyTo(q2);
    }
    
    cv::Mat optimizeImageDim(cv::Mat image)
    {
        // init
        cv::Mat padded;
        // get the optimal rows size for dft
        int addPixelRows = cv::getOptimalDFTSize(image.rows);
        // get the optimal cols size for dft
        int addPixelCols = cv::getOptimalDFTSize(image.cols);
        // apply the optimal cols and rows size to the image
        cv::copyMakeBorder(image, padded, 0, addPixelRows - image.rows, 0, addPixelCols - image.cols,
                           cv::BORDER_CONSTANT, Scalar::all(0));
    
        return padded;
    }
    
    cv::Mat createOptimizedMagnitude(cv::Mat complexImage)
    {
        // init
        std::vector<cv::Mat> newPlanes;
        cv::Mat mag = cv::Mat();
        // split the comples image in two planes
        cv::split(complexImage, newPlanes);
        // compute the magnitude
        cv::magnitude(newPlanes[0], newPlanes[1], mag);
    
        // move to a logarithmic scale
        cv::add(cv::Mat::ones(mag.size(), CV_32F), mag, mag);
        cv::log(mag, mag);
        // optionally reorder the 4 quadrants of the magnitude image
        shiftDFT(mag);
        // normalize the magnitude image for the visualization since both JavaFX
        // and OpenCV need images with value between 0 and 255
        // convert back to CV_8UC1
        mag.convertTo(mag, CV_8UC1);
        cv::normalize(mag, mag, 0, 255, cv::NORM_MINMAX, CV_8UC1);
    
        return mag;
    }
    
    cv::Mat transformImage(cv::Mat image)
    {
        // planes??????????????,???.
        if (!planes.empty()) {
            planes.clear();
        }
        // optimize the dimension of the loaded image
        cv::Mat padded = optimizeImageDim(image);
        padded.convertTo(padded, CV_32F);
        // prepare the image planes to obtain the complex image
        planes.push_back(padded);
        planes.push_back(cv::Mat::zeros(padded.size(), CV_32F));
        // prepare a complex image for performing the dft
        cv::merge(planes, complexImage);
        // dft
        printf("complexImage types %d\\n", complexImage.type());
        cv::dft(complexImage, complexImage);
    
        // optimize the image resulting from the dft operation
        cv::Mat magnitude = createOptimizedMagnitude(complexImage);
        planes.clear();
        return magnitude;
    }
    
    void transformImageWithText(cv::Mat image, String watermarkText,
                                cv::Point point, double fontSize, Scalar scalar)
    {
        // planes??????????????,???.
        if (!planes.empty()) {
            planes.clear();
        }
        // optimize the dimension of the loaded image
        cv::Mat padded = optimizeImageDim(image);
        padded.convertTo(padded, CV_32F);
        printf("padded types %d CV_32FC1 %d\\n", padded.type(), CV_32F);
        // prepare the image planes to obtain the complex image
        planes.push_back(padded);
        planes.push_back(cv::Mat::zeros(padded.size(), CV_32F));
        // prepare a complex image for performing the dft
        cv::merge(planes, complexImage);
        printf("complexImage types %d\\n", complexImage.type());
        // dft
        cv::dft(complexImage, complexImage);
        // ????????
        cv::putText(complexImage, watermarkText, point, cv::FONT_HERSHEY_DUPLEX, fontSize, scalar,2);
        cv::flip(complexImage, complexImage, -1);
        cv::putText(complexImage, watermarkText, point, cv::FONT_HERSHEY_DUPLEX, fontSize, scalar,2);
        cv::flip(complexImage, complexImage, -1);
    
        planes.clear();
    }
    
    cv::Mat antitransformImage()
    {
        cv::Mat invDFT = cv::Mat();
        cv::idft(complexImage, invDFT, cv::DFT_SCALE | cv::DFT_REAL_OUTPUT, 0);
        cv::Mat restoredImage = cv::Mat();
        invDFT.convertTo(restoredImage, CV_8U);
        planes.clear();
        return restoredImage;
    }
    
    int main(int argc, char* argv[])
    {
        if (argc < 3)
        {
            printf("watermark enc/dec file_name\\n");
        }
        else
        {
            if (strcmp(argv[1], "enc") == 0)
            {
                //load image
                Point point(50, 100);
                Scalar scalar(0, 0, 0, 0);
                printf("read file %s\\n", argv[2]);
    
                cv::Mat img1 = cv::imread(argv[2], cv::IMREAD_GRAYSCALE);
                transformImageWithText(img1, "shennug", point, 2.0, scalar);
                cv::Mat img2 = createOptimizedMagnitude(complexImage);
    
                cv::Mat img3 = antitransformImage();
    
                cv::namedWindow("Matrix1", cv::WINDOW_AUTOSIZE);
                cv::imshow("Matrix1", img1);
    
                cv::namedWindow("Matrix2", cv::WINDOW_AUTOSIZE);
                cv::imshow("Matrix2", img2);
    
                cv::namedWindow("Matrix3", cv::WINDOW_AUTOSIZE);
                cv::imshow("Matrix3", img3);
    
                cv::imwrite("1_orig.jpg", img1);
                cv::imwrite("1_watermark.jpg", img2);
    
                cv::waitKey(0);
                cv::destroyAllWindows();
            }
            if (strcmp(argv[1], "dec") == 0)
            {
                //load image
                Point point(50, 100);
                Scalar scalar(0, 0, 0, 0);
                printf("read file %s\\n", argv[2]);
    
                cv::Mat img1 = cv::imread(argv[2], cv::IMREAD_GRAYSCALE);
                transformImage(img1);
                cv::Mat img2 = createOptimizedMagnitude(complexImage);
    
                cv::Mat img3 = antitransformImage();
    
                cv::namedWindow("Matrix1", cv::WINDOW_AUTOSIZE);
                cv::imshow("Matrix1", img1);
    
                cv::namedWindow("Matrix2", cv::WINDOW_AUTOSIZE);
                cv::imshow("Matrix2", img2);
                cv::imwrite("1_decode.jpg", img2);
    
                cv::waitKey(0);
                cv::destroyAllWindows();
            }
    
        }
    
        return 1;
    
    }
    
    ln -s -f /usr/local/bin/python3.8 /usr/local/bin/python
    

    ln -s -f /usr/local/bin/pip3 /usr/local/bin/pip

    pip install opencv-python

    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python

    python

    不好用的加水印C++

    brew reinstall llvm

    Please note that, you can’t use gcc compiler on Mac-Sierra for your project which needs openMP and also openCV. You need to use llvm compiler.

    • 报错排查

      nm -g /usr/local/lib/libopencv_imgcodecs.dylib | grep imwrite 0000000000006223 T ZN2cv7imwriteERKNS_6StringERKNS_11_InputArrayERKNSt316vectorIiNS6_9allocatorIiEEEE

      nm -g main.o | grep imwrite /Library/Developer/CommandLineTools/usr/bin/nm: error: main.o: No such file or directory.

      这个报错需要换个编译器解决

    • check compiler version

      • app:
      /Applications/Clion.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -v
      
      /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -v
      
      • 换个编译器

      And rebuild/reinstall OpenCV with current version of compiler.

      • library:

    opencv 测试

    成功显示

    测试代码

    • 指定brew的执行版本。

      因为之前下载的是最新的版本4,所以要先解除4的链接

      brew unlink opencv@4
      
      brew link opencv@3 --force
      
      brew uninstall opencv
      
      opencv_version
      

      最后检查一下现在的版本

      tip: 版本3的名字是

      卸载掉之前下载的(从brew下载的最新版本)

      然后链接上版本3

    • 回到cmake

      cmake_minimum_required(VERSION 3.17)
      project(watermark_C__14)
      
      find_package(OpenCV)
      include_directories(${OpenCV_INCLUDE_DIRS})
      
      set(CMAKE_CXX_STANDARD 14)
      set(SOURCE_FILES main.cpp)
      
      add_executable(watermark_C__14 ${SOURCE_FILES})
      target_link_libraries(watermark_C__14 ${OpenCV_LIBS}) # 链接库
      

      然后就可以正常显示了

      对clion重新加载,建议最好电脑重启一下。

    • 先指定版本下载opencv3

    opencv版本

    大概意思就是说 ‘imgcodecs‘仅opencv3+版本支持。然后我就发现应该是版本问题,根据这个启发。通过homebrew对opencv版本进行重新整理

    It took me a week to solve this problem… I want to share my solution with you in detail so fewer people would get stuck with this situation.In my case, the problem lies in the conflict between opencv2 and opencv3. My ubuntu was installed with opencv 2.4.9 before by someone else, but I didn’t manage to find the build file of it and uninstall it. I learned somewhere that ‘imgcodecs’ only exists in opencv 3+, so I realized that caffe must have used opencv2 and then run into this mistake.I used cmake-gui to install opencv 3.4.3 (without clicking BUILD_opencv_world), and CMAKE_INSTALL_PREFIX was set to usr/local/opencv343 (whatever u like, just set to be separated from opencv2, which was installed in the default path). Then add usr/local/opencv343/lib to ‘sudo gedit /etc/ld.so.conf.d/opencv.conf’, and add ‘PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig export PKG_CONFIG_PATH’ to ‘sudo gedit /etc/bash.bashrc’.Then put ‘usr/local/opencv343/include’ and ‘usr/local/opencv343/lib’ behind the ‘(PYTHON INCLUDE)’ and ‘(PYTHON LIB)’ in the makefile.config respectively (before other paths).This works for me, where my ubuntu has both opencv 2 and 3. Hope it would work for you guys too.

    原话是这样的。

    后来发现是opencv库的问题,在github上找到了一点启发

    cannot find -lopencv_imgcodecs

    运行又报错了

    哦!天呐!顺滑顺滑顺滑!

    brew 和 gcc都更新好,并且修改新路径后。 编译过程就变得崭新且如丝般顺滑~倍儿爽~

    查看自己的版本号,在Clion中修改complier路径

    进入

    Clion要修改配置,不然编译的时候可能会出现报错。gcc版本更新问题

    cmake

    将旧的安装包清理掉

    brew cleanup

    brew 更新后可以用

    提示出现了一点小报错,按照提示继续安装

    于是我更换了homebrew镜像源。替换Homebrew源. 替换homebrew-core源.

    我出现了Undefined symbols for architecture x86_64: 的报错

    报错

    • 通过pip安装

      sudo python3 -m pip install opencv-python
      
    • 检验是否安装成功

      在iterm下输入

      python3

      import cv2
      print(cv2.__version__)
      

      如果显示版本号则安装成功

    python安装opencv库

    project的名字,自己命名,我这里取的是opencv。你自己命名后,要相应的修改cmake

    "OpenCV 4.x+ requires enabled C++11 support"![Screen Shot 2020-08-23 at 10.29.49 AM](/Users/KarlieLee/Library/Application Support/typora-user-images/Screen Shot 2020-08-23 at 10.29.49 AM.png)

    • cmake文件配置

      使用C++11标准

    clion配置opencv环境

    要下载的包很多,慢慢等会。

评论