首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

OpenCV cvSet2D 鼠標繪圖邊界越界問題分析與修正

     編輯:程式設計綜合問答

使用 OpenCV C 接口(IplImage、cvSet2D)實現鼠標繪圖時,若不檢查座標範圍,滑鼠移動到圖像邊緣外會導致數組越界,程序崩潰或行為異常。

問題代碼片段

void onMouseCallback(int event, int x, int y, int flags, void* param) {
    IplImage* img = (IplImage*)param;
    // ... 事件處理 ...
    if (LFlag) {
        cvSet2D(img, point.y, point.x, CV_RGB(255,0,0)); // 無邊界檢查
    }
}

當 x >= img->width 或 y >= img->height 時,cvSet2D 訪問非法內存。

修正方案:添加邊界檢查

if (LFlag) {
    if (point.x >= 0 && point.x < img->width &&
        point.y >= 0 && point.y < img->height) {
        cvSet2D(img, point.y, point.x, CV_RGB(255,0,0));
    }
}

進階建議:遷移至 C++ 接口(cv::Mat)

C 接口(IplImage、cvSet2D)已棄用,現代 OpenCV 推薦使用 C++ 接口:

#include 
using namespace cv;

Mat img(500, 500, CV_8UC3, Scalar(255,255,255));
bool drawing = false;

void onMouse(int event, int x, int y, int, void*) {
    if (event == EVENT_LBUTTONDOWN) drawing = true;
    else if (event == EVENT_LBUTTONUP) drawing = false;
    else if (event == EVENT_MOUSEMOVE && drawing) {
        if (x >= 0 && x < img.cols && y >= 0 && y < img.rows)
            img.at(y, x) = Vec3b(0, 0, 255); // BGR
    }
}

int main() {
    namedWindow("Paint");
    setMouseCallback("Paint", onMouse);
    while (waitKey(1) != 27) imshow("Paint", img);
    return 0;
}

優點:Mat 自動管理內存,at() 含邊界檢查(Debug 模式),代碼更安全簡潔。

總結

  • 鼠標回調中必須檢查座標是否在圖像範圍內再操作像素。
  • 新項目請使用 C++ 接口 (cv::Mat),避免手動內存管理與不安全的 C API。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved