Init commit
This commit is contained in:
@@ -0,0 +1,547 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user