我正在尝试通过 iOS 上的 OpenCV 使用特征检测,但遇到了一个难题:
features2d 依赖于 highgui highgui 不能在 iOS 上构建(或者至少不是我能弄清楚的)。
这让我相信:如果不重写模块以删除对 cvSaveImage() 和 cvLoadImage() 的调用,就无法在 iOS 上使用 features2d。这是错的吗?有人遇到这个并解决了吗?
您采取了错误的方法,您不需要 highgui,因为该库只是为了让您更轻松地处理处理结果,您可以简单地手动执行这些步骤。
例如,考虑这个 HOG 示例:
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
int
main(int argc, char *argv[])
{
const char *imagename = argc > 1 ? argv[1] : "../../image/pedestrian.png";
cv::Mat img = cv::imread(imagename, 1);
if(img.empty()) return -1;
cv::HOGDescriptor hog;
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
std::vector<cv::Rect> found;
// 画像,検出結果,閾値(SVMのhyper-planeとの距離),
// 探索窓の移動距離(Block移動距離の倍数),
// 画像外にはみ出た対象を探すためのpadding,
// 探索窓のスケール変化係数,グルーピング係数
hog.detectMultiScale(img, found, 0.2, cv::Size(8,8), cv::Size(16,16), 1.05, 2);
std::vector<cv::Rect>::const_iterator it = found.begin();
std::cout << "found:" << found.size() << std::endl;
for(; it!=found.end(); ++it) {
cv::Rect r = *it;
// 描画に際して,検出矩形を若干小さくする
r.x += cvRound(r.width*0.1);
r.width = cvRound(r.width*0.8);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
cv::rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
}
// 結果の描画
cv::namedWindow("result", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
cv::imshow( "result", img );
cv::waitKey(0);
}
它是为非 iOS 环境而设计的,但是您可以简单地将所有 highgui 调用替换为原生 iOS 内容。
您可以从这里为 opencv 库获得非常好的图像处理:
http://aptogo.co.uk/2011/09/opencv-framework-for-ios/
所以你应该在那个代码中真正关心的是这部分:
cv::HOGDescriptor hog;
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
std::vector<cv::Rect> found;
// 画像,検出結果,閾値(SVMのhyper-planeとの距離),
// 探索窓の移動距離(Block移動距離の倍数),
// 画像外にはみ出た対象を探すためのpadding,
// 探索窓のスケール変化係数,グルーピング係数
hog.detectMultiScale(img, found, 0.2, cv::Size(8,8), cv::Size(16,16), 1.05, 2);
std::vector<cv::Rect>::const_iterator it = found.begin();
std::cout << "found:" << found.size() << std::endl;
for(; it!=found.end(); ++it) {
cv::Rect r = *it;
// 描画に際して,検出矩形を若干小さくする
r.x += cvRound(r.width*0.1);
r.width = cvRound(r.width*0.8);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
cv::rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
}
简要说明:
// You get your img into a cv mat from the uiimage or whatever.
cv::Mat gray_img;
cv::cvtColor(img, gray_img, CV_BGR2GRAY);
cv::normalize(gray_img, gray_img, 0, 255, cv::NORM_MINMAX);
std::vector<cv::KeyPoint> keypoints;
std::vector<cv::KeyPoint>::iterator itk;
cv::Mat descriptors;
//
// threshold=0.05, edgeThreshold=10.0
cv::SiftFeatureDetector detector(0.05,10.0);
detector.detect(gray_img, keypoints);
// Brief に基づくディスクリプタ抽出器
cv::BriefDescriptorExtractor extractor;
cv::Scalar color(50,50,155);
extractor.compute(gray_img, keypoints, descriptors);
// 32次元の特徴量 x keypoint数
for(int i=0; i<descriptors.rows; ++i) {
cv::Mat d(descriptors, cv::Rect(0,i,descriptors.cols,1));
std::cout << i << ": " << d << std::endl;
}
你有你的结果。