c++ - 具有颜色之间依赖关系的颜色过滤
问题描述
我目前的目标是制作一个滤色器(可能是阈值),为具有以下关系的区域创建一个蒙版:
B < G
G > 128
R > 1.5 * G
我已经创建了这样的算法,但它会遍历图像的每个像素并手动检测是否满足这些条件。哪个 - 正如您可能已经猜到的那样 - 相当慢。
在之前的机器 (NUCi7) 上,生成的程序可以达到大约 6-10 FPS,但它完全在 CPU 上运行。现在我切换到 Jetson Xavier NX 来看看 GPU 加速的 OpenCV。目前我正在寻找一个或几个功能,可以以一种有效的方式实现这些条件。
我不是想找到最有效的方法,如果一开始就太复杂的话。但是我测试了一些对象跟踪算法,这些算法在 40+ FPS 和 HD2K 图像上的工作就像一个魅力,所以我希望有一种方法可以完成这项工作并最终达到 40+/60+ FPS。
像inRange函数这样的东西会很棒,但对于 GPU-OpenCV 来说似乎还不存在。也许有一种聪明的方法可以用thresholds来实现它,但到目前为止我只是用静态值找到它。
.
https://docs.opencv.org/2.4/modules/gpu/doc/image_processing.html
image.forEach<Pixel>
(
[&](Pixel &pixel, const int * position) -> void
{
if (pixel.z > 1.5 * pixel.y &&
(pixel.y > pixel.x) &&
pixel.y > 128){
pixel.z = 255;
pixel.y = 255;
pixel.x = 255;
} else {
pixel.z = 0;
pixel.y = 0;
pixel.x = 0;
}
}
);
代码基本上就是我想从这里开始的代码。从上面应用 foreach 循环。
实际的当前代码是这个:
while (viewer.isAvailable()) {
// Grab images
if (zed.grab(runtime_parameters) == ERROR_CODE::SUCCESS) {
// Retrieve left image
zed.retrieveImage(image_zed, VIEW::LEFT, MEM::GPU,new_image_size);
cv::Mat image_ocv = slMat2cvMat(image_zed);
// <!-- Everything here is a test to insert a custom 3D-Bounding box into the live-image
sl::ObjectData newObject;
sl::ObjectData refObject;
std::cout << "\n\nNew Loop" << endl;
// Retrieve Detected Human Bodies
zed.retrieveObjects(objects, objectTracker_parameters_rt);
int id = 42;
sl::float3 newPosition = {-.1,.1,-0.5};
sl::float3 newVelocity = {.0,.0,.0};
std::vector<sl::float3> newBounding_box;
sl::float3 pOri = {looper[0],looper[1],looper[2]};
sl::float3 pDim = {0.25,0.25,0.25};
sl::float3 p0 = {pOri[0]-pDim[0]/2,pOri[1]-pDim[1]/2,pOri[2]-pDim[2]/2};
sl::float3 p1 = {pOri[0]-pDim[0]/2,pOri[1]-pDim[1]/2,pOri[2]+pDim[2]/2};
sl::float3 p2 = {pOri[0]+pDim[0]/2,pOri[1]-pDim[1]/2,pOri[2]+pDim[2]/2};
sl::float3 p3 = {pOri[0]+pDim[0]/2,pOri[1]-pDim[1]/2,pOri[2]-pDim[2]/2};
sl::float3 p4 = {pOri[0]-pDim[0]/2,pOri[1]+pDim[1]/2,pOri[2]-pDim[2]/2};
sl::float3 p5 = {pOri[0]-pDim[0]/2,pOri[1]+pDim[1]/2,pOri[2]+pDim[2]/2};
sl::float3 p6 = {pOri[0]+pDim[0]/2,pOri[1]+pDim[1]/2,pOri[2]+pDim[2]/2};
sl::float3 p7 = {pOri[0]+pDim[0]/2,pOri[1]+pDim[1]/2,pOri[2]-pDim[2]/2};
std::vector<sl::uint2> newBounding_box_2d = {
{250,30},
{1500,30},
{1500,500},
{250,500}};
newBounding_box.push_back(p0);
newBounding_box.push_back(p1);
newBounding_box.push_back(p2);
newBounding_box.push_back(p3);
newBounding_box.push_back(p4);
newBounding_box.push_back(p5);
newBounding_box.push_back(p6);
newBounding_box.push_back(p7);
sl::float3 newDimensions = {1.0,1.0,1.0};
newObject.id = id;
newObject.position = pOri;
newObject.velocity = newVelocity;
newObject.bounding_box_2d = newBounding_box_2d;
newObject.bounding_box = newBounding_box;
newObject.dimensions = pDim;
objects.object_list.push_back(newObject);
// --> End of the 3D-Bounding box insert
/* image_ocv.forEach<Pixel>
(
[&](Pixel &pixel, const int * position) -> void {
if (pixel.z > 1.5 * pixel.y && pixel.y > pixel.x && pixel.y > 128) {
pixel.z = 255; pixel.y = 255; pixel.x = 255;
} else {
pixel.z = 0; pixel.y = 0; pixel.x = 0;
}
}
);*/
//Update GL View
viewer.updateView(image_zed, objects);
}
}
cv::Mat slMat2cvMat(Mat& input) {
// Mapping between MAT_TYPE and CV_TYPE
int cv_type = -1;
switch (input.getDataType()) {
case MAT_TYPE::F32_C1: cv_type = CV_32FC1; break;
case MAT_TYPE::F32_C2: cv_type = CV_32FC2; break;
case MAT_TYPE::F32_C3: cv_type = CV_32FC3; break;
case MAT_TYPE::F32_C4: cv_type = CV_32FC4; break;
case MAT_TYPE::U8_C1: cv_type = CV_8UC1; break;
case MAT_TYPE::U8_C2: cv_type = CV_8UC2; break;
case MAT_TYPE::U8_C3: cv_type = CV_8UC3; break;
case MAT_TYPE::U8_C4: cv_type = CV_8UC4; break;
default: break;
}
// Since cv::Mat data requires a uchar* pointer, we get the uchar1 pointer from sl::Mat (getPtr<T>())
// cv::Mat and sl::Mat will share a single memory structure
return cv::Mat(input.getHeight(), input.getWidth(), cv_type, input.getPtr<sl::uchar1>(MEM::GPU));
}
代码按原样工作,但添加ForEach-Loop
会导致分段错误。
解决方案
推荐阅读
- ios - iOS 13 上 UITextField 中的 URL 被修剪
- python - 使用 r2pipe 进行多处理
- scala - Play Framework - 手动升级到 Web socket
- c - 如何使用缓存线原子性在 CPU 之间复制多个数据元素?
- android - isInViewport for Android
- bash - 使用字母数字字符串上的一般数值进行 Bash 排序未返回正确排序的行
- android - 如何使自定义类从 LinearLayout 扩展并在其中包含两个视图
- python - 在行中写入csv文件解析html中的几种css样式
- android - 将 Flutter 应用程序迁移到 AndroidX 后,Flutter 卡在安装 build\app\outputs\apk\app.apk
- php - 如何在 Opencart 的另一个 PHP 文件(不是控制器文件)中调用控制器类?