C++OpenCV矩形的角点检测与坐标提取,基于fast特征点

目的:提取图片中某个矩形的四个角点的坐标

方法:采用非极大值抑制的fast特征点检测

流程:

  1. 图像滤波(可选)
  2. fast角点检测
  3. 自己设定矩形大致范围
  4. 输出矩形角点坐标

程序:

主函数文件

#include 
using namespace cv;
using namespace std;
//局部极大值抑制,这里利用fast特征点的响应值做比较
void selectMax(int window, cv::Mat gray, std::vector & kp){

    //window是局部极大值抑制的窗口大小,r为半径
    int r = window / 2;
    if (window != 0){
        //对kp中的点进行局部极大值筛选
        for (int i = 0; i < kp.size(); i++){
            for (int j = i + 1; j < kp.size(); j++){
                //如果两个点的距离小于半径r,则删除其中响应值较小的点
                if (abs(kp[i].pt.x - kp[j].pt.x) + abs(kp[i].pt.y - kp[j].pt.y) <= 2 * r){
                    if (kp[i].response < kp[j].response){
                        std::vector::iterator it = kp.begin() + i;
                        kp.erase(it);
                        selectMax(window, gray, kp);
                    }
                    else{
                        std::vector::iterator it = kp.begin() + j;
                        kp.erase(it);
                        selectMax(window, gray, kp);
                    }
                }
            }
        }
    }

}

//
void fastpoint(cv::Mat gray, int threshold, int window, int pointNum, std::vector & kp){

    std::vector keypoint;

   // cv::FastFeatureDetector fast(threshold, 1);  //threshold 为阈值,越大,特征点越少
  //  fast.detect(gray, keypoint);  //fast特征检测
    Ptr fast = FastFeatureDetector::create(threshold);
fast->detect(gray, keypoint);
    if (keypoint.size() > pointNum){
        threshold = threshold + 5;
        fastpoint(gray, threshold, window, pointNum, keypoint);
    }
    selectMax(window, gray, keypoint);
    kp.assign(keypoint.begin(), keypoint.end());    //复制可以point到kp

}

int main(){
    cv::Mat img = cv::imread("/home/csdn/123.jpeg");
    cv::Mat gray;
    
    //medianBlur(img,img, 5); //中值滤波
    GaussianBlur(img, img, Size(5, 5), 0.8); //高斯滤波
    
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
    std::vector kp;
    int threshold = 20;  //fast阈值
    int window1 = 7;  //局部非极大值抑制窗口
    int pointMaxNum1 = 500; //特征点最大个数
    fastpoint(gray, threshold, window1, pointMaxNum1, kp);
    //矩形框
     int x1 ;
    int x2 ;
    int y1 ;
    int y2;
       //自己设置多大的矩形框
            x1=250 ;
     x2=259 ;
     y1=247 ;
     y2=260;
    
   vector temp;
    for(vector::iterator it = kp.begin();itpt.x < x2 && it->pt.x > x1 &&it->pt.y < y2 && it->pt.y > y1)
        {
            cout <<"角点坐标"<pt< kp2;
    img.copyTo(img2);
    gray.copyTo(gray2);
    int window2 = 15;  //局部非极大值抑制窗口
    int pointMaxNum2 = 600; //特征点最大个数
    fastpoint(gray2, threshold, window2, pointMaxNum2, kp2);
*/
    cv::drawKeypoints(img, kp, img, Scalar(0, 0, 255));
    cv::rectangle(img,Rect(x1,y1,x2-x1,y2-y1),(0, 0, 255),2);

    cv::imwrite("/home/csdn/123_1.jpeg", img);    //保存结果图片
    cv::namedWindow("img", cv::WINDOW_NORMAL);
    cv::imshow("img", img);    //展示结果图片

    cv::waitKey(0);

    system("pause");
    return 0;
}

我使用cmake编译

CMakeLists.txt


cmake_minimum_required(VERSION 2.8)
project(vo1)

set(CMAKE_BUILD_TYPE "Release")
add_definitions("-DENABLE_SSE")
set(CMAKE_CXX_FLAGS "-std=c++14 ${SSE_FLAGS} -msse4")
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
set(OpenCV_DIR /usr/lib/x86_64-linux-gnu/cmake/opencv4)	//我的opencv库的位置
find_package(OpenCV  REQUIRED)

include_directories(
        ${OpenCV_INCLUDE_DIRS}
)

add_executable(fast1 fast1.cpp)
target_link_libraries(fast1
        ${OpenCV_LIBS}
        fmt) 

网络图片涉及版权在此不做演示

代码仅供参考,欢迎学习交流

参考FAST角点检测算法(二)- 非极大值抑制筛选fast特征点_AI人工智能科学的博客-CSDN博客_角点检测非极大值抑制https://aibotlab.blog.csdn.net/article/details/73397682

你可能感兴趣的:(opencv,c++,人工智能)