29 #include <opencv2/core.hpp>
30 #include <opencv2/features2d.hpp>
31 #include <opencv2/imgcodecs.hpp>
32 #include <opencv2/imgproc.hpp>
54 #define CHECK_STATUS(STMT) \
57 VPIStatus status = (STMT); \
58 if (status != VPI_SUCCESS) \
60 char buffer[VPI_MAX_STATUS_MESSAGE_LENGTH]; \
61 vpiGetLastStatusMessage(buffer, sizeof(buffer)); \
62 std::ostringstream ss; \
63 ss << vpiStatusGetName(status) << ": " << buffer; \
64 throw std::runtime_error(ss.str()); \
71 img.convertTo(out, CV_8UC1);
72 cvtColor(out, out, cv::COLOR_GRAY2BGR);
74 if (numKeypoints == 0)
79 std::vector<int> distances(numKeypoints, 0);
82 for (
int i = 0; i < numKeypoints; i++)
86 distances[i] += std::bitset<8 * sizeof(uint8_t)>(descs[i].data[j] ^ descs[0].data[j]).count();
88 if (distances[i] > maxDist)
90 maxDist = distances[i];
95 std::iota(&ids[0], &ids[0] + 256, 0);
96 cv::Mat idsMat(256, 1, CV_8UC1, ids);
99 applyColorMap(idsMat, cmap, cv::COLORMAP_JET);
101 for (
int i = 0; i < numKeypoints; i++)
103 int cmapIdx =
static_cast<int>(std::round((distances[i] / maxDist) * 255));
105 float rescale = std::pow(2, kpts[i].octave);
106 float x = kpts[i].
x * rescale;
107 float y = kpts[i].
y * rescale;
109 circle(out, cv::Point(x, y), 3, cmap.at<cv::Vec3b>(cmapIdx, 0), -1);
115 int main(
int argc,
char *argv[])
140 throw std::runtime_error(std::string(
"Usage: ") + argv[0] +
" <cpu|cuda> <input image>");
143 std::string strBackend = argv[1];
144 std::string strInputFileName = argv[2];
149 if (strBackend ==
"cpu")
153 else if (strBackend ==
"cuda")
159 throw std::runtime_error(
"Backend '" + strBackend +
"' not recognized, it must be either cpu or cuda.");
168 cvImage = cv::imread(strInputFileName);
171 throw std::runtime_error(
"Can't open first image: '" + strInputFileName +
"'");
219 backend, &pyrInput));
246 cv::Mat outImage = DrawKeypoints(img, outKeypoints, outDescriptors, *outKeypointsData.
buffer.
aos.
sizePointer);
249 imwrite(
"orb_feature_detector_" + strBackend +
".png", outImage);
256 catch (std::exception &e)
258 std::cerr << e.what() << std::endl;
用于处理 VPI 的 OpenCV 互操作性的函数。
#define VPI_BRIEF_DESCRIPTOR_ARRAY_LENGTH
Brief 描述符数组的长度。
VPIArrayBuffer buffer
存储数组内容。
int32_t * sizePointer
指向数组中元素的数量。
VPIArrayBufferAOS aos
以结构体数组布局存储的数组。
VPIStatus vpiArrayUnlock(VPIArray array)
释放数组对象的锁定。
VPIStatus vpiArrayLockData(VPIArray array, VPILockMode mode, VPIArrayBufferType bufType, VPIArrayData *data)
获取数组对象的锁定并返回数组内容。
void vpiArrayDestroy(VPIArray array)
销毁数组实例。
VPIStatus vpiArrayCreate(int32_t capacity, VPIArrayType type, uint64_t flags, VPIArray *array)
创建空数组实例。
struct VPIArrayImpl * VPIArray
数组的句柄。
@ VPI_ARRAY_TYPE_BRIEF_DESCRIPTOR
VPIBriefDescriptor 元素。
@ VPI_ARRAY_TYPE_PYRAMIDAL_KEYPOINT_F32
VPIPyramidalKeypointF32 元素。
@ VPI_ARRAY_BUFFER_HOST_AOS
主机可访问的结构体数组。
float intensityThreshold
选择像素作为关键点候选点周围圆弧一部分的阈值。
VPIStatus vpiSubmitGaussianPyramidGenerator(VPIStream stream, uint64_t backend, VPIImage input, VPIPyramid output, VPIBorderExtension border)
从输入图像计算高斯金字塔。
void vpiImageDestroy(VPIImage img)
销毁图像实例。
struct VPIImageImpl * VPIImage
图像的句柄。
VPIStatus vpiImageLockData(VPIImage img, VPILockMode mode, VPIImageBufferType bufType, VPIImageData *data)
获取图像对象的锁定并返回图像内容。
VPIStatus vpiImageCreate(int32_t width, int32_t height, VPIImageFormat fmt, uint64_t flags, VPIImage *img)
使用指定的标志创建空图像实例。
VPIStatus vpiImageUnlock(VPIImage img)
释放图像对象的锁定。
@ VPI_IMAGE_BUFFER_HOST_PITCH_LINEAR
主机可访问,平面采用 pitch-linear 内存布局。
VPIStatus vpiImageCreateWrapperOpenCVMat(const cv::Mat &mat, VPIImageFormat fmt, uint64_t flags, VPIImage *img)
使用给定的图像格式将 cv::Mat 封装到 VPIImage 中。
VPIStatus vpiImageDataExportOpenCVMat(const VPIImageData &imgData, cv::Mat *mat)
使用来自锁定 VPIImage 的 VPIImageData 数据填充现有的 cv::Mat。
int32_t maxFeaturesPerLevel
ORB 在输入金字塔的每个级别使用的最大特征数 N。
VPIFASTCornerDetectorParams fastParams
FAST 角点检测器的参数,有关更多详细信息,请参见 FAST 角点检测器。
int32_t maxPyramidLevels
要利用的输入金字塔中的最大级别数。
VPIStatus vpiInitORBParams(VPIORBParams *params)
使用默认值初始化 VPIORBParams。
VPIStatus vpiSubmitORBFeatureDetector(VPIStream stream, uint64_t backend, VPIPayload payload, VPIPyramid input, VPIArray outCorners, VPIArray outDescriptors, const VPIORBParams *params, VPIBorderExtension border)
向流提交 ORB 特征检测器操作。
VPIStatus vpiCreateORBFeatureDetector(uint64_t backends, int32_t capacity, VPIPayload *payload)
创建 ORB 特征检测器负载。
定义 vpiSubmitORBFeatureDetector 参数的结构。
struct VPIPayloadImpl * VPIPayload
算法负载的句柄。
void vpiPayloadDestroy(VPIPayload payload)
释放负载对象和所有关联的资源。
VPIStatus vpiPyramidCreate(int32_t width, int32_t height, VPIImageFormat fmt, int32_t numLevels, float scale, uint64_t flags, VPIPyramid *pyr)
使用指定的标志创建空图像金字塔实例。
struct VPIPyramidImpl * VPIPyramid
图像金字塔的句柄。
struct VPIStreamImpl * VPIStream
流的句柄。
VPIStatus vpiStreamSync(VPIStream stream)
阻止调用线程,直到此流队列中的所有已提交命令完成(队列为空)...
void vpiStreamDestroy(VPIStream stream)
销毁流实例并释放所有硬件资源。
VPIStatus vpiStreamCreate(uint64_t flags, VPIStream *stream)
创建流实例。
@ VPI_BACKEND_CUDA
CUDA 后端。
@ VPI_BORDER_LIMITED
将图像视为受限,不访问外部像素。
@ VPI_BORDER_CLAMP
无限重复边界像素。
@ VPI_LOCK_READ
仅锁定内存以进行读取。
存储 float32 基于金字塔的关键点坐标。坐标包括 (x,...