Моя текущая цель — создать цветовой фильтр (возможно, пороговый), который создает маску для областей с чем-то вроде следующих отношений:
B < G
G > 128
R > 1.5 * G
Я уже создал такой алгоритм, но он перебирает каждый пиксель изображения и вручную определяет, выполняются ли эти условия. Что, как вы уже догадались, довольно медленное.
На предыдущей машине (NUCi7) результирующая программа могла достигать примерно 6-10 кадров в секунду, но она выполнялась полностью на процессоре. Теперь я переключился на Jetson Xavier NX, чтобы посмотреть на 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
приводит к ошибке сегментации.
Я задал дополнительный вопрос, который может быть ответом на этот вопрос.
G > 128
, ... - person Jean-Marc Volle   schedule 13.11.2020