本文共 4392 字,大约阅读时间需要 14 分钟。
斑点分类器是一个基于直方图和关键点的多分类器,该分类器能够根据输入图像中的斑点生成相应的分类结果。该分类器通过计算输入图像中的特征描述符,并与已知描述符进行比较,来确定图像所属的类别。
#include "BlobClassifier.hpp"#include#include #ifdef WITH_OPENCV_CONTRIB#include #endifconst int HISTOGRAM_NUM_BINS_PER_CHANNEL = 32;const int HISTOGRAM_COMPARISON_METHOD = cv::HISTCMP_CHISQR_ALT;const float HISTOGRAM_DISTANCE_WEIGHT = 0.98f;const float KEYPOINT_MATCHING_DISTANCE_WEIGHT = 1.0f - HISTOGRAM_DISTANCE_WEIGHT;
BlobClassifier::BlobClassifier() : clahe(cv::createCLAHE()) { #ifdef WITH_OPENCV_CONTRIB , featureDetectorAndDescriptorExtractor(cv::xfeatures2d::SURF::create()) , descriptorMatcher(cv::DescriptorMatcher::create("FlannBased")) #else , featureDetectorAndDescriptorExtractor(cv::ORB::create()) , descriptorMatcher(cv::DescriptorMatcher::create("BruteForce-HammingLUT")) #endif} void BlobClassifier::update(const Blob &referenceBlob) { referenceBlobDescriptors.push_back(createBlobDescriptor(referenceBlob));} void BlobClassifier::clear() { referenceBlobDescriptors.clear();} void BlobClassifier::classify(Blob &detectedBlob) const { BlobDescriptor detectedBlobDescriptor = createBlobDescriptor(detectedBlob); float bestDistance = FLT_MAX; uint32_t bestLabel = 0; for (const BlobDescriptor &referenceBlobDescriptor : referenceBlobDescriptors) { float distance = findDistance(detectedBlobDescriptor, referenceBlobDescriptor); if (distance < bestDistance) { bestDistance = distance; bestLabel = referenceBlobDescriptor.getLabel(); } } detectedBlob.setLabel(bestLabel);} BlobDescriptor BlobClassifier::createBlobDescriptor(const Blob &blob) const { const cv::Mat &mat = blob.getMat(); int numChannels = mat.channels(); // Calculate the histogram of the blob's image. cv::Mat histogram; int channels[] = {0, 1, 2}; int numBins[] = {HISTOGRAM_NUM_BINS_PER_CHANNEL, HISTOGRAM_NUM_BINS_PER_CHANNEL, HISTOGRAM_NUM_BINS_PER_CHANNEL}; float range[] = {0.0f, 256.0f}; const float *ranges[] = {range, range, range}; cv::calcHist(&mat, 1, channels, cv::Mat(), histogram, 3, numBins, ranges); // Normalize the histogram. histogram *= (1.0f / (mat.rows * mat.cols)); // Convert the blob's image to grayscale. cv::Mat grayMat; switch (numChannels) { case 4: cv::cvtColor(mat, grayMat, cv::COLOR_BGRA2GRAY); break; default: cv::cvtColor(mat, grayMat, cv::COLOR_BGR2GRAY); break; } // Detect features in the grayscale image. std::vector keypoints; featureDetectorAndDescriptorExtractor->detect(grayMat, keypoints); // Extract descriptors of the features. cv::Mat keypointDescriptors; featureDetectorAndDescriptorExtractor->compute(grayMat, keypoints, keypointDescriptors); return BlobDescriptor(histogram, keypointDescriptors, blob.getLabel());} float BlobClassifier::findDistance(const BlobDescriptor &detectedBlobDescriptor, const BlobDescriptor &referenceBlobDescriptor) const { float histogramDistance = (float)cv::compareHist(detectedBlobDescriptor.getNormalizedHistogram(), referenceBlobDescriptor.getNormalizedHistogram(), HISTOGRAM_COMPARISON_METHOD); float keypointMatchingDistance = 0.0f; std::vector keypointMatches; descriptorMatcher->match(detectedBlobDescriptor.getKeypointDescriptors(), referenceBlobDescriptor.getKeypointDescriptors(), keypointMatches); for (const cv::dmatch &keypointMatch : keypointMatches) { keypointMatchingDistance += keypointMatch.distance; } return histogramDistance * HISTOGRAM_DISTANCE_WEIGHT + keypointMatchingDistance * KEYPOINT_MATCHING_DISTANCE_WEIGHT;} #include "BlobDescriptor.hpp"BlobDescriptor::BlobDescriptor(const cv::Mat &normalizedHistogram, const cv::Mat &keypointDescriptors, uint32_t label) : normalizedHistogram(normalizedHistogram), keypointDescriptors(keypointDescriptors), label(label) {}const cv::Mat &BlobDescriptor::getNormalizedHistogram() const { return normalizedHistogram;}const cv::Mat &BlobDescriptor::getKeypointDescriptors() const { return keypointDescriptors;}uint32_t BlobDescriptor::getLabel() const { return label;} 该分类器通过将图像转换为灰度并提取特征来进行分类。特征包括颜色直方图和关键点描述符。直方图和关键点的匹配距离结合计算,用于最终分类结果。代码采用了不同的特征检测算法(如SURF或ORB)以及相应的描述符匹配方法,以适应不同的性能需求。
转载地址:http://lqxez.baihongyu.com/