我正在尝试在android应用程序中实现一些计算机视觉。
我已经集成了opencv,我正在为它编写使用JNI调用的原生c++代码。这一切似乎都在起作用。我的问题是,当执行计算机视觉代码时,下面的一行会使应用程序崩溃,没有任何错误。
detector->detectAndCompute(usr_img,usr_mask,usr_keypoints,usr_descriptors);
如果我使用球体探测器,而不是筛选,它确实有效。在我的物理设备上,它在knnMatch上崩溃。而在模拟的Pixel 5上,它可以正确完成。也许这与我的opencv和android版本有关?
这是完整的计算机视觉代码:
void process_image(char* in_filepath,char* out_filepath){
Mat usr_img = imread(in_filepath); //read images from the disk
Mat ref_img = imread("redacted");
Mat overlay_img = imread("redacted");
Mat out_img;//make a copy for output
usr_img.copyTo(out_img);
//Set up feature detector
Ptr<SIFT> detector = SIFT::create();
//Ptr<ORB> detector = ORB::create(); //detectAndCompute works if I use this instead
//Set up feature matcher
Ptr<BFMatcher> matcher = BFMatcher::create(NORM_HAMMING,true);
//generate mask for ref image (so features are not created from the background)
Mat ref_mask; //defines parts of the ref image that will be searched for features.
inRange(ref_img,Scalar(0.0,0.0,252.0),Scalar(2.0,2.0,255.0),ref_mask);
bitwise_not(ref_mask,ref_mask);//invert the mask
//and an all white mask for the usr image
Mat usr_mask = Mat(usr_img.cols,usr_img.rows, CV_8UC1, Scalar(255.0));
//detect keypoints
std::vector<KeyPoint> ref_keypoints, usr_keypoints;
Mat ref_descriptors, usr_descriptors;
detector->detectAndCompute(ref_img,ref_mask,ref_keypoints,ref_descriptors);
detector->detectAndCompute(usr_img,usr_mask,usr_keypoints,usr_descriptors);
//match descriptors between images, each match is a vector of matches by decreasing "distance"
std::vector<std::vector<DMatch>> matches;
matcher->knnMatch(usr_descriptors,ref_descriptors,matches,2);
//throw out bad matches
std::vector<DMatch> good_matches;
for(uint32_t i = 0; i < matches.size(); i++){
//consider it a good match if the next best match is 33% worse
if(matches[i][0].distance*1.33 < matches[i][1].distance){
good_matches.push_back(matches[i][0]);
}
}
//visualize the matches for debugging purposes
Mat draw_match_img;
drawMatches(usr_img,usr_keypoints,ref_img,ref_keypoints,good_matches,draw_match_img);
imwrite("redacted",draw_match_img);
}
我的opencv版本是4.5.4
我的android版本在物理手机上是9,在模拟像素5 上是11,api 30
我发现了问题。
我的图片是4000x3000px和大约3000x1600。将两个图像都缩小2倍,可以使一切正常工作。
我在每次imread后添加了一个调整大小的按钮,如下所示:
resize(x_img,x_img,Size(),0.5,0.5,INTER_CUBIC);
这个告诉我的是,opencv 4.5.4中的SIFT有一个图像大小限制,超过这个限制,执行将崩溃,而不会出现错误消息。。烦人的
它还解释了为什么有些检测器工作,有些不工作,甚至当我在真实设备上运行它时,与模拟设备相比,它似乎有所不同。