547 lines
28 KiB
C++
547 lines
28 KiB
C++
#ifndef ZCPPWIN_ZCV_H
|
|
#define ZCPPWIN_ZCV_H
|
|
|
|
|
|
/*
|
|
* zcv.h
|
|
* -----------------------------------------------------------------------------
|
|
* 基于 OpenCV 4.x / opencv_contrib 4.x 的常用计算机视觉工具库声明文件。
|
|
*
|
|
* 设计目标:
|
|
* 1. 将 OpenCV 中高频使用的图像、视频、特征、DNN、二维码/条码、ArUco、标定等
|
|
* 操作整理成统一的 ZCV 命名空间,减少项目中的重复样板代码。
|
|
* 2. 保持“薄封装”原则:函数内部仍然使用 OpenCV 原生数据结构,如 cv::Mat、cv::Rect、
|
|
* cv::Point2f、cv::dnn::Net,便于和既有 OpenCV 代码互操作。
|
|
* 3. 尽量兼容 OpenCV 4.x 的不同小版本。对 contrib 中可能不存在或 API 变化较大的模块,
|
|
* 使用 __has_include 与版本宏做条件编译。
|
|
*
|
|
* 使用方式:
|
|
* #include "zcv.h"
|
|
* cv::Mat img = ZCV::readImage("test.jpg");
|
|
* cv::Mat gray = ZCV::ensureGray(img);
|
|
* cv::Mat edges = ZCV::canny(gray, 80, 160);
|
|
*
|
|
* 编译提示:
|
|
* CMake 中通常写法:
|
|
* find_package(OpenCV 4 REQUIRED)
|
|
* add_library(zcv zcv.cpp)
|
|
* target_include_directories(zcv PUBLIC ${OpenCV_INCLUDE_DIRS})
|
|
* target_link_libraries(zcv PUBLIC ${OpenCV_LIBS})
|
|
*/
|
|
|
|
#include <opencv2/core.hpp>
|
|
#include <opencv2/core/version.hpp>
|
|
#include <opencv2/imgproc.hpp>
|
|
#include <opencv2/imgcodecs.hpp>
|
|
#include <opencv2/highgui.hpp>
|
|
#include <opencv2/videoio.hpp>
|
|
// #include <opencv2/video.hpp>
|
|
#include <opencv2/calib3d.hpp>
|
|
// #include <opencv2/features2d.hpp>
|
|
// #include <opencv2/objdetect.hpp>
|
|
#include <opencv2/dnn.hpp>
|
|
// #include <opencv2/photo.hpp>
|
|
|
|
// #include <algorithm>
|
|
#include <cstdint>
|
|
// #include <limits>
|
|
// #include <map>
|
|
// #include <stdexcept>
|
|
#include <string>
|
|
// #include <utility>
|
|
#include <vector>
|
|
|
|
// ---------------------------- 可选 contrib 模块检测 ----------------------------
|
|
// ArUco 在 OpenCV 4.x 的不同小版本中经历过头文件与 API 调整;优先使用传统 aruco.hpp,
|
|
// 若新版本只提供 objdetect 下的头文件,也尝试包含。
|
|
#if __has_include(<opencv2/aruco.hpp>)
|
|
#include <opencv2/aruco.hpp>
|
|
#define ZCV_HAS_ARUCO 1
|
|
#elif __has_include(<opencv2/objdetect/aruco_detector.hpp>) && __has_include(<opencv2/objdetect/aruco_dictionary.hpp>)
|
|
#include <opencv2/objdetect/aruco_detector.hpp>
|
|
#include <opencv2/objdetect/aruco_dictionary.hpp>
|
|
#define ZCV_HAS_ARUCO 1
|
|
#else
|
|
#define ZCV_HAS_ARUCO 0
|
|
#endif
|
|
|
|
// barcode 模块属于 contrib/objdetect 体系,不同版本头文件位置可能不同。
|
|
#if __has_include(<opencv2/objdetect/barcode.hpp>)
|
|
#include <opencv2/objdetect/barcode.hpp>
|
|
#define ZCV_HAS_BARCODE 1
|
|
#elif __has_include(<opencv2/barcode.hpp>)
|
|
#include <opencv2/barcode.hpp>
|
|
#define ZCV_HAS_BARCODE 1
|
|
#else
|
|
#define ZCV_HAS_BARCODE 0
|
|
#endif
|
|
|
|
// SIFT 在较新的 OpenCV 4.x 中位于 features2d;较旧版本可能在 xfeatures2d。
|
|
#if (CV_VERSION_MAJOR > 4) || (CV_VERSION_MAJOR == 4 && CV_VERSION_MINOR >= 4)
|
|
#define ZCV_HAS_SIFT 1
|
|
#elif __has_include(<opencv2/xfeatures2d.hpp>)
|
|
#include <opencv2/xfeatures2d.hpp>
|
|
#define ZCV_HAS_SIFT 1
|
|
#define ZCV_SIFT_IN_XFEATURES2D 1
|
|
#else
|
|
#define ZCV_HAS_SIFT 0
|
|
#endif
|
|
|
|
namespace ZCV {
|
|
|
|
// =============================================================================
|
|
// 1. 基础枚举与数据结构
|
|
// =============================================================================
|
|
|
|
/** 图像缩放模式。 */
|
|
enum class ResizeMode {
|
|
Stretch, ///< 直接拉伸到目标尺寸,可能改变宽高比。
|
|
KeepAspectFit, ///< 保持宽高比完整放入目标画布,不足区域填充颜色,类似 letterbox。
|
|
KeepAspectFill ///< 保持宽高比并填满目标尺寸,多余区域居中裁剪。
|
|
};
|
|
|
|
/** 常用形态学操作类型。 */
|
|
enum class MorphType {
|
|
Erode, ///< 腐蚀:缩小白色前景区域。
|
|
Dilate, ///< 膨胀:扩大白色前景区域。
|
|
Open, ///< 开运算:先腐蚀后膨胀,常用于去除小噪声。
|
|
Close, ///< 闭运算:先膨胀后腐蚀,常用于填补小孔洞。
|
|
Gradient, ///< 形态学梯度:突出目标边界。
|
|
TopHat, ///< 顶帽:原图 - 开运算结果,突出小亮区域。
|
|
BlackHat, ///< 黑帽:闭运算结果 - 原图,突出小暗区域。
|
|
HitMiss ///< 击中击不中,仅适用于二值单通道图像。
|
|
};
|
|
|
|
/** 90 度倍数旋转模式。 */
|
|
enum class RotateMode {
|
|
Clockwise90, ///< 顺时针旋转 90 度。
|
|
CounterClockwise90, ///< 逆时针旋转 90 度。
|
|
Rotate180 ///< 旋转 180 度。
|
|
};
|
|
|
|
/** 图像基本信息,便于调试日志输出。 */
|
|
struct ImageInfo {
|
|
bool empty = true; ///< cv::Mat 是否为空。
|
|
int width = 0; ///< 图像宽度,单位:像素。
|
|
int height = 0; ///< 图像高度,单位:像素。
|
|
int channels = 0; ///< 通道数。
|
|
int depth = -1; ///< OpenCV 深度,例如 CV_8U、CV_32F。
|
|
int type = -1; ///< OpenCV 完整类型,例如 CV_8UC3。
|
|
std::string typeString; ///< 便于阅读的类型字符串,例如 "CV_8UC3"。
|
|
};
|
|
|
|
/** letterbox 缩放的返回结果。 */
|
|
struct LetterboxResult {
|
|
cv::Mat image; ///< 输出图像,尺寸等于 targetSize。
|
|
double scale = 1.0; ///< 原图到缩放图的比例。
|
|
int padLeft = 0; ///< 左侧填充像素数。
|
|
int padTop = 0; ///< 顶部填充像素数。
|
|
cv::Rect contentRect; ///< 原图缩放后在目标画布中的区域。
|
|
};
|
|
|
|
/** 轮廓摘要信息。 */
|
|
struct ContourInfo {
|
|
std::vector<cv::Point> contour; ///< 原始轮廓点。
|
|
double area = 0.0; ///< 轮廓面积,来自 cv::contourArea。
|
|
double perimeter = 0.0; ///< 轮廓周长,来自 cv::arcLength。
|
|
cv::Rect boundingBox; ///< 水平外接矩形。
|
|
cv::RotatedRect rotatedBox; ///< 最小面积旋转外接矩形。
|
|
cv::Point2f center; ///< 根据矩计算出的质心;矩退化时取外接框中心。
|
|
float enclosingRadius = 0.0f; ///< 最小外接圆半径。
|
|
double circularity = 0.0; ///< 圆形度,4*pi*area/perimeter^2,越接近 1 越圆。
|
|
};
|
|
|
|
/** 连通域摘要信息。 */
|
|
struct ComponentInfo {
|
|
int label = -1; ///< 连通域标签,0 通常是背景。
|
|
int area = 0; ///< 像素面积。
|
|
cv::Rect boundingBox; ///< 外接矩形。
|
|
cv::Point2d centroid; ///< 质心。
|
|
};
|
|
|
|
/** 特征检测结果。 */
|
|
struct FeatureResult {
|
|
std::vector<cv::KeyPoint> keypoints; ///< 关键点列表。
|
|
cv::Mat descriptors; ///< 描述子矩阵。
|
|
};
|
|
|
|
/** 两幅图像特征匹配结果。 */
|
|
struct MatchResult {
|
|
FeatureResult first; ///< 第一幅图像特征。
|
|
FeatureResult second; ///< 第二幅图像特征。
|
|
std::vector<cv::DMatch> matches; ///< 通过筛选的匹配。
|
|
cv::Mat homography; ///< 若启用单应性估计,则保存 3x3 H 矩阵。
|
|
std::vector<char> inlierMask; ///< RANSAC 内点掩码,与 matches 一一对应。
|
|
int inlierCount = 0; ///< 内点数量。
|
|
};
|
|
|
|
/** 棋盘格角点检测结果。 */
|
|
struct ChessboardResult {
|
|
bool found = false; ///< 是否成功找到所有内角点。
|
|
cv::Size boardSize; ///< 棋盘格内角点数量,width x height。
|
|
std::vector<cv::Point2f> corners; ///< 角点坐标。
|
|
cv::Mat debugImage; ///< 绘制角点后的调试图。
|
|
};
|
|
|
|
/** 相机标定结果。 */
|
|
struct CalibrationResult {
|
|
bool ok = false; ///< 标定是否执行成功。
|
|
double reprojectionError = 0.0; ///< cv::calibrateCamera 返回的重投影误差。
|
|
cv::Mat cameraMatrix; ///< 3x3 内参矩阵。
|
|
cv::Mat distCoeffs; ///< 畸变系数。
|
|
std::vector<cv::Mat> rvecs; ///< 每张标定图的旋转向量。
|
|
std::vector<cv::Mat> tvecs; ///< 每张标定图的平移向量。
|
|
std::size_t usedImageCount = 0; ///< 实际参与标定的图片数量。
|
|
};
|
|
|
|
/** 视频文件或摄像头的摘要信息。 */
|
|
struct VideoInfo {
|
|
bool opened = false; ///< 是否成功打开。
|
|
int width = 0; ///< 帧宽。
|
|
int height = 0; ///< 帧高。
|
|
double fps = 0.0; ///< 帧率;摄像头或部分文件可能返回 0。
|
|
int frameCount = 0; ///< 总帧数;实时流可能返回 0 或不可靠值。
|
|
double durationSec = 0.0; ///< 估算时长,frameCount / fps。
|
|
std::string backendName; ///< OpenCV 使用的视频后端名称。
|
|
};
|
|
|
|
/** QRCodeDetector 单个二维码识别结果。 */
|
|
struct QRCodeResult {
|
|
bool success = false; ///< 是否检测并解码出非空字符串。
|
|
std::string text; ///< 解码文本,OpenCV 通常返回 UTF-8 字符串。
|
|
std::vector<cv::Point2f> points; ///< 二维码四个角点。
|
|
cv::Mat straight; ///< 透视校正后的二维码图像,可为空。
|
|
};
|
|
|
|
#if ZCV_HAS_ARUCO
|
|
/** ArUco marker 检测结果。 */
|
|
struct ArucoResult {
|
|
std::vector<int> ids; ///< marker ID 列表。
|
|
std::vector<std::vector<cv::Point2f>> corners; ///< 每个 marker 的四个角点。
|
|
std::vector<std::vector<cv::Point2f>> rejected; ///< 被拒绝的候选区域,便于调参。
|
|
};
|
|
#endif
|
|
|
|
#if ZCV_HAS_BARCODE
|
|
/** 条形码检测与解码结果。 */
|
|
struct BarcodeResult {
|
|
bool success = false; ///< 是否成功解码。
|
|
std::string text; ///< 解码文本。
|
|
std::string type; ///< 条码类型,如 EAN_13、CODE_128 等,具体取决于 OpenCV。
|
|
std::vector<cv::Point2f> points; ///< 条码旋转矩形四个点;可能因版本差异为空。
|
|
};
|
|
#endif
|
|
|
|
/** DNN 前处理参数。 */
|
|
struct DnnOptions {
|
|
cv::Size inputSize; ///< 网络输入尺寸;空尺寸表示不强制 resize。
|
|
double scale = 1.0; ///< 像素缩放因子,例如 1/255.0。
|
|
cv::Scalar mean = cv::Scalar(); ///< 均值,按 BGR 或 RGB 顺序取决于 swapRB。
|
|
bool swapRB = false; ///< 是否交换 R/B 通道,常用于 BGR -> RGB。
|
|
bool crop = false; ///< blobFromImage 是否中心裁剪。
|
|
int ddepth = CV_32F; ///< blob 数据深度,一般为 CV_32F。
|
|
int backend = cv::dnn::DNN_BACKEND_OPENCV; ///< 推理后端。
|
|
int target = cv::dnn::DNN_TARGET_CPU; ///< 推理目标设备。
|
|
std::string inputName; ///< setInput 的输入层名称,通常留空。
|
|
};
|
|
|
|
/** DNN 推理结果。 */
|
|
struct DnnForwardResult {
|
|
std::vector<cv::Mat> outputs; ///< 网络输出 blob 列表。
|
|
double inferenceMs = 0.0; ///< 单次 forward 耗时,单位毫秒。
|
|
};
|
|
|
|
/** 分类分数。 */
|
|
struct ClassScore {
|
|
int classId = -1; ///< 类别索引。
|
|
float score = 0.0f; ///< 置信度或概率。
|
|
};
|
|
|
|
/** 简单计时器,基于 cv::TickMeter。 */
|
|
class TickTimer {
|
|
public:
|
|
void start(); ///< 清零并开始计时。
|
|
double stopMs(); ///< 停止计时并返回毫秒数。
|
|
double elapsedMs() const; ///< 返回当前累计毫秒数。
|
|
private:
|
|
cv::TickMeter meter_;
|
|
};
|
|
|
|
// =============================================================================
|
|
// 2. 基础信息、类型转换与安全检查
|
|
// =============================================================================
|
|
|
|
std::string opencvVersionString();
|
|
std::string matTypeToString(int type);
|
|
ImageInfo getImageInfo(const cv::Mat& image);
|
|
bool isGray(const cv::Mat& image);
|
|
bool isBgrLike(const cv::Mat& image);
|
|
bool hasAlpha(const cv::Mat& image);
|
|
void assertNotEmpty(const cv::Mat& image, const std::string& name = "image");
|
|
cv::Mat ensureGray(const cv::Mat& image);
|
|
cv::Mat ensureBgr(const cv::Mat& image);
|
|
cv::Mat ensureBgra(const cv::Mat& image);
|
|
cv::Mat to8U(const cv::Mat& image, bool normalize = true, double alpha = 1.0, double beta = 0.0);
|
|
cv::Mat toFloat32(const cv::Mat& image, double scale = 1.0 / 255.0);
|
|
|
|
// =============================================================================
|
|
// 3. 图像读写、显示与基础矩阵操作
|
|
// =============================================================================
|
|
|
|
cv::Mat readImage(const std::string& path, int flags = cv::IMREAD_COLOR, bool throwIfEmpty = true);
|
|
bool saveImage(const std::string& path, const cv::Mat& image,
|
|
const std::vector<int>& params = std::vector<int>());
|
|
std::vector<cv::Mat> readImages(const std::vector<std::string>& paths,
|
|
int flags = cv::IMREAD_COLOR,
|
|
bool skipFailed = true);
|
|
void showImage(const std::string& windowName, const cv::Mat& image,
|
|
int delayMs = 0, int windowFlags = cv::WINDOW_AUTOSIZE,
|
|
bool destroyAfter = false);
|
|
cv::Rect clampRect(const cv::Rect& roi, const cv::Size& imageSize);
|
|
cv::Mat crop(const cv::Mat& image, const cv::Rect& roi, bool safe = true, bool clone = true);
|
|
cv::Mat centerCrop(const cv::Mat& image, const cv::Size& size, bool clone = true);
|
|
std::vector<cv::Mat> splitChannels(const cv::Mat& image);
|
|
cv::Mat mergeChannels(const std::vector<cv::Mat>& channels);
|
|
cv::Mat stackHorizontal(const std::vector<cv::Mat>& images, int gap = 0,
|
|
const cv::Scalar& background = cv::Scalar(0, 0, 0));
|
|
cv::Mat stackVertical(const std::vector<cv::Mat>& images, int gap = 0,
|
|
const cv::Scalar& background = cv::Scalar(0, 0, 0));
|
|
cv::Mat makeGrid(const std::vector<cv::Mat>& images, int columns,
|
|
cv::Size cellSize = cv::Size(), int gap = 0,
|
|
const cv::Scalar& background = cv::Scalar(0, 0, 0));
|
|
|
|
// =============================================================================
|
|
// 4. 几何变换
|
|
// =============================================================================
|
|
|
|
cv::Mat resizeTo(const cv::Mat& image, const cv::Size& targetSize,
|
|
ResizeMode mode = ResizeMode::Stretch,
|
|
int interpolation = cv::INTER_LINEAR,
|
|
const cv::Scalar& borderColor = cv::Scalar(114, 114, 114));
|
|
cv::Mat resizeScale(const cv::Mat& image, double fx, double fy = 0.0,
|
|
int interpolation = cv::INTER_LINEAR);
|
|
LetterboxResult letterbox(const cv::Mat& image, const cv::Size& targetSize,
|
|
const cv::Scalar& color = cv::Scalar(114, 114, 114),
|
|
bool allowScaleUp = true,
|
|
int interpolation = cv::INTER_LINEAR);
|
|
cv::Mat rotate90(const cv::Mat& image, RotateMode mode);
|
|
cv::Mat rotateAngle(const cv::Mat& image, double angleDeg, double scale = 1.0,
|
|
bool expand = true,
|
|
const cv::Scalar& borderValue = cv::Scalar(0, 0, 0));
|
|
cv::Mat translate(const cv::Mat& image, double dx, double dy,
|
|
const cv::Scalar& borderValue = cv::Scalar(0, 0, 0));
|
|
std::vector<cv::Point2f> orderQuadPoints(const std::vector<cv::Point2f>& points);
|
|
cv::Mat fourPointTransform(const cv::Mat& image, const std::vector<cv::Point2f>& points,
|
|
int interpolation = cv::INTER_LINEAR);
|
|
cv::Mat warpPerspectiveFromPoints(const cv::Mat& image,
|
|
const std::vector<cv::Point2f>& srcPoints,
|
|
const std::vector<cv::Point2f>& dstPoints,
|
|
const cv::Size& dstSize,
|
|
int interpolation = cv::INTER_LINEAR);
|
|
|
|
// =============================================================================
|
|
// 5. 图像增强与滤波
|
|
// =============================================================================
|
|
|
|
cv::Mat adjustBrightnessContrast(const cv::Mat& image, double alpha = 1.0, double beta = 0.0);
|
|
cv::Mat gammaCorrect(const cv::Mat& image, double gamma);
|
|
cv::Mat equalizeGray(const cv::Mat& image);
|
|
cv::Mat clahe(const cv::Mat& image, double clipLimit = 2.0,
|
|
cv::Size tileGridSize = cv::Size(8, 8));
|
|
cv::Mat normalizeMinMax(const cv::Mat& image, double alpha = 0.0, double beta = 255.0,
|
|
int dtype = -1);
|
|
cv::Mat grayWorldWhiteBalance(const cv::Mat& image);
|
|
cv::Mat sharpen(const cv::Mat& image);
|
|
cv::Mat unsharpMask(const cv::Mat& image, double amount = 1.0, double sigma = 1.0);
|
|
cv::Mat denoise(const cv::Mat& image, float h = 10.0f, float hColor = 10.0f,
|
|
int templateWindowSize = 7, int searchWindowSize = 21);
|
|
cv::Mat applyColorMapToGray(const cv::Mat& image, int colorMap = cv::COLORMAP_JET);
|
|
cv::Mat meanBlur(const cv::Mat& image, int ksize = 3);
|
|
cv::Mat gaussianBlur(const cv::Mat& image, int ksize = 5, double sigmaX = 0.0);
|
|
cv::Mat medianBlur(const cv::Mat& image, int ksize = 5);
|
|
cv::Mat bilateral(const cv::Mat& image, int d = 9, double sigmaColor = 75.0, double sigmaSpace = 75.0);
|
|
cv::Mat sobelEdges(const cv::Mat& image, int dx = 1, int dy = 0, int ksize = 3);
|
|
cv::Mat laplacianEdges(const cv::Mat& image, int ksize = 3);
|
|
cv::Mat calcGrayHist(const cv::Mat& image, int histSize = 256, float rangeMin = 0.0f, float rangeMax = 256.0f);
|
|
cv::Mat drawGrayHist(const cv::Mat& hist, cv::Size canvasSize = cv::Size(512, 300),
|
|
const cv::Scalar& color = cv::Scalar(255, 255, 255));
|
|
|
|
// =============================================================================
|
|
// 6. 二值化、边缘、形态学与距离变换
|
|
// =============================================================================
|
|
|
|
cv::Mat thresholdBinary(const cv::Mat& image, double thresh, double maxVal = 255.0,
|
|
bool inverse = false);
|
|
cv::Mat thresholdOtsu(const cv::Mat& image, double maxVal = 255.0, bool inverse = false);
|
|
cv::Mat adaptiveThresholdBinary(const cv::Mat& image, int blockSize = 31, double C = 5.0,
|
|
bool inverse = false,
|
|
int method = cv::ADAPTIVE_THRESH_GAUSSIAN_C);
|
|
cv::Mat canny(const cv::Mat& image, double threshold1, double threshold2,
|
|
int apertureSize = 3, bool L2gradient = false);
|
|
cv::Mat morph(const cv::Mat& image, MorphType type, int kernelSize = 3, int iterations = 1,
|
|
int shape = cv::MORPH_RECT);
|
|
cv::Mat erodeImage(const cv::Mat& image, int kernelSize = 3, int iterations = 1,
|
|
int shape = cv::MORPH_RECT);
|
|
cv::Mat dilateImage(const cv::Mat& image, int kernelSize = 3, int iterations = 1,
|
|
int shape = cv::MORPH_RECT);
|
|
cv::Mat fillHoles(const cv::Mat& binaryImage);
|
|
cv::Mat distanceTransformBinary(const cv::Mat& binaryImage, int distanceType = cv::DIST_L2,
|
|
int maskSize = 3);
|
|
|
|
// =============================================================================
|
|
// 7. 轮廓、连通域与几何度量
|
|
// =============================================================================
|
|
|
|
std::vector<ContourInfo> findContoursInfo(const cv::Mat& binaryImage,
|
|
int retrievalMode = cv::RETR_EXTERNAL,
|
|
int approximation = cv::CHAIN_APPROX_SIMPLE,
|
|
double minArea = 0.0,
|
|
bool sortByAreaDesc = true);
|
|
bool largestContour(const cv::Mat& binaryImage, ContourInfo& outInfo, double minArea = 0.0);
|
|
cv::Mat drawContourInfos(const cv::Mat& image, const std::vector<ContourInfo>& contours,
|
|
const cv::Scalar& color = cv::Scalar(0, 255, 0),
|
|
int thickness = 2, bool drawBoundingBox = true,
|
|
bool drawIndex = false);
|
|
cv::Mat contourMask(const cv::Size& size, const std::vector<cv::Point>& contour,
|
|
uchar fillValue = 255);
|
|
std::vector<ComponentInfo> connectedComponentsInfo(const cv::Mat& binaryImage,
|
|
int connectivity = 8,
|
|
int minArea = 1);
|
|
cv::Mat drawComponents(const cv::Mat& labels, int labelCount);
|
|
double intersectionOverUnion(const cv::Rect2f& a, const cv::Rect2f& b);
|
|
cv::Scalar randomColor(int seed, int minValue = 40, int maxValue = 255);
|
|
|
|
// =============================================================================
|
|
// 8. 特征点、描述子与匹配
|
|
// =============================================================================
|
|
|
|
FeatureResult detectORB(const cv::Mat& image, int nfeatures = 1000);
|
|
FeatureResult detectAKAZE(const cv::Mat& image);
|
|
#if ZCV_HAS_SIFT
|
|
FeatureResult detectSIFT(const cv::Mat& image, int nfeatures = 0);
|
|
#endif
|
|
std::vector<cv::DMatch> matchDescriptors(const cv::Mat& desc1, const cv::Mat& desc2,
|
|
int normType = -1,
|
|
bool crossCheck = false,
|
|
double ratio = 0.75,
|
|
int maxMatches = 0);
|
|
MatchResult matchORB(const cv::Mat& image1, const cv::Mat& image2,
|
|
int nfeatures = 1500, double ratio = 0.75,
|
|
bool estimateHomography = true,
|
|
double ransacReprojThreshold = 3.0);
|
|
cv::Mat drawMatchResult(const cv::Mat& image1, const cv::Mat& image2,
|
|
const MatchResult& result,
|
|
bool onlyInliers = true);
|
|
|
|
// =============================================================================
|
|
// 9. 相机标定、畸变校正与传统目标检测
|
|
// =============================================================================
|
|
|
|
ChessboardResult findChessboard(const cv::Mat& image, cv::Size boardSize,
|
|
bool refineSubPix = true,
|
|
int flags = cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_NORMALIZE_IMAGE);
|
|
CalibrationResult calibrateCameraFromChessboards(const std::vector<cv::Mat>& images,
|
|
cv::Size boardSize,
|
|
float squareSize,
|
|
int flags = 0);
|
|
CalibrationResult calibrateCameraFromChessboardFiles(const std::vector<std::string>& imagePaths,
|
|
cv::Size boardSize,
|
|
float squareSize,
|
|
int flags = 0);
|
|
cv::Mat undistortImage(const cv::Mat& image, const cv::Mat& cameraMatrix,
|
|
const cv::Mat& distCoeffs, double alpha = 0.0);
|
|
std::vector<cv::Rect> detectHaar(const cv::Mat& image, const std::string& cascadePath,
|
|
double scaleFactor = 1.1, int minNeighbors = 3,
|
|
cv::Size minSize = cv::Size(), cv::Size maxSize = cv::Size());
|
|
cv::Mat drawRects(const cv::Mat& image, const std::vector<cv::Rect>& rects,
|
|
const cv::Scalar& color = cv::Scalar(0, 255, 0), int thickness = 2);
|
|
|
|
// =============================================================================
|
|
// 10. DNN:模型加载、blob 前处理、推理与后处理辅助
|
|
// =============================================================================
|
|
|
|
cv::dnn::Net loadDnnNet(const std::string& modelPath,
|
|
const std::string& configPath = std::string(),
|
|
const std::string& framework = std::string(),
|
|
int backend = cv::dnn::DNN_BACKEND_OPENCV,
|
|
int target = cv::dnn::DNN_TARGET_CPU);
|
|
cv::Mat makeBlob(const cv::Mat& image, const DnnOptions& options);
|
|
DnnForwardResult forwardDnn(cv::dnn::Net& net, const cv::Mat& image,
|
|
const DnnOptions& options,
|
|
const std::vector<std::string>& outputNames = std::vector<std::string>());
|
|
std::vector<ClassScore> topK(const cv::Mat& scores, int k = 5);
|
|
std::vector<int> nmsBoxes(const std::vector<cv::Rect>& boxes,
|
|
const std::vector<float>& confidences,
|
|
float scoreThreshold = 0.25f,
|
|
float nmsThreshold = 0.45f,
|
|
float eta = 1.0f,
|
|
int topK = 0);
|
|
|
|
// =============================================================================
|
|
// 11. 视频读取、写入与帧抽取
|
|
// =============================================================================
|
|
|
|
VideoInfo getCaptureInfo(cv::VideoCapture& cap);
|
|
cv::VideoCapture openVideo(const std::string& path, int apiPreference = cv::CAP_ANY,
|
|
bool throwIfFailed = true);
|
|
cv::VideoCapture openCamera(int index = 0, int width = 0, int height = 0,
|
|
double fps = 0.0, int apiPreference = cv::CAP_ANY,
|
|
bool throwIfFailed = true);
|
|
bool readFrameAt(const std::string& videoPath, int frameIndex, cv::Mat& frame,
|
|
int apiPreference = cv::CAP_ANY);
|
|
cv::VideoWriter createVideoWriter(const std::string& path, cv::Size frameSize, double fps,
|
|
const std::string& fourcc = "MJPG", bool isColor = true,
|
|
int apiPreference = cv::CAP_ANY);
|
|
bool writeVideoFromFrames(const std::string& path, const std::vector<cv::Mat>& frames,
|
|
double fps, const std::string& fourcc = "MJPG",
|
|
bool isColor = true);
|
|
std::vector<cv::Mat> readAllFrames(const std::string& videoPath, int maxFrames = -1,
|
|
int step = 1, int apiPreference = cv::CAP_ANY);
|
|
int extractFrames(const std::string& videoPath, const std::string& outputPattern,
|
|
int step = 1, int maxFrames = -1, int startFrame = 0,
|
|
int apiPreference = cv::CAP_ANY);
|
|
|
|
// =============================================================================
|
|
// 12. 二维码、条码、ArUco 与绘制辅助
|
|
// =============================================================================
|
|
|
|
QRCodeResult detectAndDecodeQRCode(const cv::Mat& image);
|
|
cv::Mat drawQRCodeResult(const cv::Mat& image, const QRCodeResult& result,
|
|
const cv::Scalar& color = cv::Scalar(0, 255, 0));
|
|
|
|
#if ZCV_HAS_BARCODE
|
|
std::vector<BarcodeResult> detectAndDecodeBarcodes(const cv::Mat& image,
|
|
const std::string& srPrototxt = std::string(),
|
|
const std::string& srModel = std::string());
|
|
cv::Mat drawBarcodeResults(const cv::Mat& image, const std::vector<BarcodeResult>& results,
|
|
const cv::Scalar& color = cv::Scalar(255, 0, 0));
|
|
#endif
|
|
|
|
#if ZCV_HAS_ARUCO
|
|
ArucoResult detectArucoMarkers(const cv::Mat& image,
|
|
int dictionaryId = cv::aruco::DICT_4X4_50,
|
|
bool refineCorners = true);
|
|
cv::Mat drawArucoResult(const cv::Mat& image, const ArucoResult& result,
|
|
const cv::Scalar& color = cv::Scalar(0, 255, 0));
|
|
cv::Mat generateArucoMarker(int markerId, int sidePixels = 300,
|
|
int dictionaryId = cv::aruco::DICT_4X4_50,
|
|
int borderBits = 1);
|
|
#endif
|
|
|
|
void drawLabel(cv::Mat& image, const std::string& text, cv::Point origin,
|
|
double fontScale = 0.6,
|
|
const cv::Scalar& textColor = cv::Scalar(255, 255, 255),
|
|
const cv::Scalar& bgColor = cv::Scalar(0, 0, 0),
|
|
int thickness = 1);
|
|
void drawRotatedRect(cv::Mat& image, const cv::RotatedRect& rect,
|
|
const cv::Scalar& color = cv::Scalar(0, 255, 0), int thickness = 2);
|
|
void drawCrosshair(cv::Mat& image, cv::Point center, int radius = 10,
|
|
const cv::Scalar& color = cv::Scalar(0, 0, 255), int thickness = 1);
|
|
cv::Mat drawGridOverlay(const cv::Mat& image, int gridSize = 50,
|
|
const cv::Scalar& color = cv::Scalar(80, 80, 80),
|
|
int thickness = 1);
|
|
|
|
} // namespace ZCV
|
|
|
|
|
|
#endif //ZCPPWIN_ZCV_H
|