gpt4 book ai didi

ios - 从 Objective C++ 调用时,OpenCv inRange 函数的行为不同

转载 作者:可可西里 更新时间:2023-11-01 05:48:46 24 4
gpt4 key购买 nike

我在这里对这个问题使用了很好的答案:

How to detect bullet holes on the target using python

我已经验证它适用于 Python 2 和 3.6,但我想在用 Objective C(++) 编写的 iOS 应用程序中使用这个概念。这是我翻译它的尝试。最终,我需要它处理相机拍摄的图像,所以我不想使用 imread,但我已经检查过这没有任何区别。

UIImage *nsi = [UIImage imageNamed:@"CANDX.jpg"];
cv::Mat original;
UIImageToMat(nsi, original);

cv::Mat thresholded;
cv::inRange(original, cv::Scalar(40,40,40), cv::Scalar(160,160,160), thresholded);

cv::Mat kernel = cv::Mat::ones(10, 10, CV_64FC1);
cv::Mat opening;
cv::morphologyEx(thresholded, opening, cv::MORPH_OPEN, kernel);

vector<vector<cv::Point>> contours;
cv::findContours(opening, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);

调用 inRange,使用与 Python 版本相同的值,给出一个全黑的图像。事实上,不可能选择不会导致此结果的下限和上限值。我试过将图像转换为 HSV 并使用 HSV 值作为下限和上限。这略有不同,因为我可以获得一些模糊可辨的结果,但与我应该获得的有用结果完全不同。

如果我从答案中替换“阈值”图像并注释掉 inRange 调用,则 morphologyfindContours 调用可以正常工作。

我在设置 inRange 调用时做错了什么吗?

最佳答案

正如您在评论中提到的,original 的数据类型是 CV_8UC4 —— 即它是一个 4 channel 图像。但是,在您调用 cv::inRange 时,您仅提供 3 个 channel 的范围。

cv::Scalar表示一个 4 元素向量。当您调用 constructor只有 3 个值,默认值 0 用于第 4 个元素。

因此,您对 inRange 的调用实际上等同于:

cv::inRange(original, cv::Scalar(40,40,40,0), cv::Scalar(160,160,160,0), thresholded);

您只查找将 alpha channel 设置为 0(完全透明)的像素。由于图像来自相机,因此不太可能存在任何透明像素 - alpha channel 可能全都是 255s。

有两个选项可以解决这个问题:

  • 删除不需要的 alpha channel 。一种方法是使用 cv::cvtColor ,例如

    cv::cvtColor(original, original, cv::COLOR_BGRA2BGR);
  • 为所有 channel 指定所需的范围,例如

    cv::inRange(original, cv::Scalar(40,40,40,0), cv::Scalar(160,160,160,255), thresholded);

关于ios - 从 Objective C++ 调用时,OpenCv inRange 函数的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48856966/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com