подскажите пожалуйста есть ли графические библиотеки быстрей чем opencv для операций
ресайзинга изображений
совмещения нескольких изображений
изменения кодировки цветов
у меня сейчас CPU грузиться на 100%
насколько я смог разобраться в opencv использование GPU от Intel работает только для кодирования декодирования видео
есть флаг использовать CUDA для математических вычеслений, но у меня ограничение использовать только оборудование от Intel
Здравствуйте, sergey2b, Вы писали:
S>подскажите пожалуйста есть ли графические библиотеки быстрей чем opencv для операций S>ресайзинга изображений https://habr.com/ru/post/301576/https://uploadcare.com/blog/the-fastest-production-ready-image-resize/ S>совмещения нескольких изображений S>изменения кодировки цветов
S>у меня сейчас CPU грузиться на 100%
это же просто замечательно, значит вы загружаете все ресурсы
S>насколько я смог разобраться в opencv использование GPU от Intel работает только для кодирования декодирования видео S>есть флаг использовать CUDA для математических вычеслений, но у меня ограничение использовать только оборудование от Intel
CUDA может только nvidia, остальные OpenCL либо metal
А что у вас за оборудование? И какой производительности вы хотите достичь?
Здравствуйте, sergey2b, Вы писали:
S>у меня сейчас CPU грузиться на 100% S>насколько я смог разобраться в opencv использование GPU от Intel работает только для кодирования декодирования видео
На Интела она вполне хороша. Два нюанса:
1. При работе на CPU убедиться, что собрана с IPP и использует его.
2. Используй OpenCL (это называется TAPI, задействуется через cv::UMat) на Интеловской GPU.
Здравствуйте, sergey2b, Вы писали:
S>подскажите пожалуйста есть ли графические библиотеки быстрей чем opencv для операций S>ресайзинга изображений S>совмещения нескольких изображений S>изменения кодировки цветов
S>у меня сейчас CPU грузиться на 100% S>насколько я смог разобраться в opencv использование GPU от Intel работает только для кодирования декодирования видео S>есть флаг использовать CUDA для математических вычеслений, но у меня ограничение использовать только оборудование от Intel
Здравствуйте, sergey2b, Вы писали:
S>подскажите пожалуйста есть ли графические библиотеки быстрей чем opencv
Если на Windows, бери Direct3D 11, он в коробке с ОС.
Основных минусов два, с ним удобно работать только на C++, и если раньше не имел дел с аппаратной 3D графикой, уйдёт заметное время на обучение.
S>ресайзинга изображений
Если увеличивать, или аппаратный bilinear sampler (быстрее и проще), или напиши на HLSL pixel или compute shader, который сделает bicubic (лучше качество).
Если уменьшать, генерируй пирамиду mip levels методом ID3D11DeviceContext::GenerateMips, потом trilinear sampler. S>совмещения нескольких изображений
Рендерить затекстуренные прямоугольники довольно дёшево. S>изменения кодировки цветов
Проще всего compute shader по 1 потоку на пиксель. Или если кодировка вроде NV12, можно compute shader по 1 потоку на 4 пикселя.
Здравствуйте, Nuzhny, Вы писали:
N>На Интела она вполне хороша. Два нюанса: N>1. При работе на CPU убедиться, что собрана с IPP и использует его. N>2. Используй OpenCL (это называется TAPI, задействуется через cv::UMat) на Интеловской GPU.
я пересобрад opencv с IPP сапорт
вы можете посмотреть это инфо сборки
// Include Libraries
#include "opencv2/core.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
#ifdef _WIN64
#if _DEBUG
//#pragma comment(lib, "opencv_world454d.lib")
#pragma comment(lib, "opencv_world455.lib")
#else
#pragma comment(lib, "opencv_world455.lib")
#endif
#endif
// Namespace to nullify use of cv::function(); syntax
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
char* filename = argv[1];
if (!filename) return -1;
string sret = cv::getBuildInformation();
cout << sret << endl;
ocl::setUseOpenCL(true);
bool oclhaveOpenCL = ocl::haveOpenCL();
bool ocluseOpenCL = ocl::useOpenCL();
std::cout << oclhaveOpenCL << " " << ocluseOpenCL << std::endl;
// initialize a video capture object
//VideoCapture video1(filename, cv::CAP_INTEL_MFX);
VideoCapture video1(filename);
// Print error message if the stream is invalid
if (!video1.isOpened())
{
cout << "Error opening video stream or file" << endl;
}
else
{
// Obtain fps and frame count by get() method and print
// You can replace 5 with CAP_PROP_FPS as well, they are enumerations
int fps = video1.get(5);
cout << "Frames per second :" << fps;
// Obtain frame_count using opencv built in frame count reading method
// You can replace 7 with CAP_PROP_FRAME_COUNT as well, they are enumerations
int frame_count = video1.get(7);
cout << " Frame count :" << frame_count;
}
// Read the frames to the last frame
while (video1.isOpened())
{
// Initialise frame matrix
cv::UMat frame1;
// Initialize a boolean to check if frames are there or not
bool isSuccess = video1.read(frame1);
// If frames are present, show it
if (isSuccess == true)
{
// Load 4 images from the disk
cv::UMat img1 = frame1;
cv::UMat img2 = frame1;
cv::UMat img3 = frame1;
cv::UMat img4 = frame1;
// Make sure they have been loaded successfully
if (img1.empty() || img2.empty() || img3.empty() || img4.empty())
{
std::cout << "!!! Failed to load one of the images\n";
return -1;
}
/* Make sure they are compatible: same type, depth and # channels */
if ((img1.type() != img2.type()) ||
(img3.type() != img4.type()) ||
(img1.type() != img4.type()))
{
std::cout << "!!! The depth doesn't match!\n";
return -1;
}
if ((img1.depth() != img2.depth()) ||
(img3.depth() != img4.depth()) ||
(img1.depth() != img4.depth()))
{
std::cout << "!!! The depth doesn't match!\n";
return -1;
}
if ((img1.channels() != img2.channels()) ||
(img3.channels() != img4.channels()) ||
(img1.channels() != img4.channels()))
{
std::cout << "!!! Number of channels doesn't match!\n";
return -1;
}
// Create the destination image based on the size of the loaded images
// _________
// | | |
// |_1__|_2__|
// | | |
// |_3__|_4__|
/* As the input images might have different sizes, we need to make sure
* to create an output image that is big enough to store all of them.
*/
// Compute the width of the output image
int row1_size = img1.size().width + img2.size().width;
int row2_size = img3.size().width + img4.size().width;
int new_width = std::max(row1_size, row2_size);
// Compute the height of the output image
int col1_size = img1.size().height + img3.size().height;
int col2_size = img2.size().height + img4.size().height;
int new_height = std::max(col1_size, col2_size);
// Create the destination image
cv::UMat dst_img(cv::Size(new_width, new_height), img1.type(), cv::Scalar(0, 0, 0));
std::cout << "dst: size " << dst_img.size().width << "x" << dst_img.size().height << std::endl;
/* Copy the pixels of the input images to the destination */
// _________
// | | |
// |_1__| |
// | |
// |_________|
img1.copyTo(dst_img(cv::Rect(0, 0, img1.cols, img1.rows)));
// _________
// | | |
// |_1__|_2__|
// | |
// |_________|
img2.copyTo(dst_img(cv::Rect(img1.size().width, 0, img2.cols, img2.rows)));
// _________
// | | |
// |_1__|_2__|
// | | |
// |_3__|____|
img3.copyTo(dst_img(cv::Rect(0,
std::max(img1.size().height, img2.size().height),
img3.cols,
img3.rows)));
// _________
// | | |
// |_1__|_2__|
// | | |
// |_3__|_4__|
img4.copyTo(dst_img(cv::Rect(img3.size().width,
std::max(img1.size().height, img2.size().height),
img4.cols,
img4.rows)));
// For testing purposes, display it on the screen
cv::imshow("Test", dst_img);
cv::waitKey(1);
}
// If frames are not there, close it
if (isSuccess == false)
{
cout << "Video camera is disconnected" << endl;
break;
}
}
// Release the video capture object
video1.release();
destroyAllWindows();
return 0;
}
если использовать VideoCapture video1(filename, cv::CAP_INTEL_MFX); то я вижу как нагржуаеться intel GPU
но я не вижу как UMat используют GPU
но я не вижу в таскменеджере что GPU от Intel используеться хотя бы на 1%
Здравствуйте, sergey2b, Вы писали:
S>я пересобрад opencv с IPP сапорт S>вы можете посмотреть это инфо сборки
Ага, раз с ним соббрано, значит и используется. Единственно, что там и использовать особо негде — просто копирование кадров.
S>это тестовый код
А что он выводит? OpenCL используется или нет? Кроме того, можно указывать OpenCL device, на котором должно выполняться, а также выводить список этих самых устройств.
Ну и замечание по коду. Все cv::Mat и cv::UMat надо определять вне цикла. Даже временные Mat надо переиспользовать, делать их членами класса, например. Дело в том, что OpenCV заново не будет выделять память под такие объекты, если они его устраивают. Так что большую картинку уж точно не надо объявлять внутри. Если же мы говорим про UMat, то это вообще безумие — так обращаться с видеопамятью.
N>А что он выводит? OpenCL используется или нет? Кроме того, можно указывать OpenCL device, на котором должно выполняться, а также выводить список этих самых устройств. N>Ну и замечание по коду. Все cv::Mat и cv::UMat надо определять вне цикла. Даже временные Mat надо переиспользовать, делать их членами класса, например. Дело в том, что OpenCV заново не будет выделять память под такие объекты, если они его устраивают. Так что большую картинку уж точно не надо объявлять внутри. Если же мы говорим про UMat, то это вообще безумие — так обращаться с видеопамятью.
спасибо за советы, все заработал
в реальном коде я создаю объекты в начале функции
вот пример в котором при замене Mat на UMat видна разница в производительности
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/ocl.hpp>
#include <iostream>
#include <chrono>
#ifdef _WIN64
#if _DEBUG
#pragma comment(lib, "opencv_world454d.lib")
#else
//#pragma comment(lib, "opencv_world454.lib")
#pragma comment(lib, "opencv_world455.lib")
#endif
#endif
using namespace std;
using namespace cv;
int main()
{
cout << "Have OpenCL?: " << cv::ocl::haveOpenCL() << endl; // returns true, OCL available
ocl::setUseOpenCL(true);
//ocl::setUseOpenCL(false);
//cv::ocl::Context context((1 << 2));
cv::ocl::Context context;
if (!context.create(cv::ocl::Device::TYPE_GPU))
{
cout << "Failed creating the context..." << endl;
return 0;
}
cout << context.ndevices() << " GPU devices are detected." << endl;
for (int i = 0; i < context.ndevices(); i++)
{
cv::ocl::Device device = context.device(i);
cout << "name : " << device.name() << endl;
cout << "available : " << device.available() << endl;
cout << "imageSupport : " << device.imageSupport() << endl;
cout << "OpenCL_C_Version : " << device.OpenCL_C_Version() << endl;
cout << endl;
}
// Load images test1.jpg, ..., test7.jpg
vector<UMat> images;
for (int i = 1; i <= 7; i++)
{
string filename = "c:\\tmp\\test" + to_string(i) + ".jpg";
UMat input = imread(filename).getUMat(ACCESS_READ);
images.push_back(input);
}
for (int i = 0; i < 7; i++)
{
chrono::high_resolution_clock::time_point begin = chrono::high_resolution_clock::now();
// ---------------------- Critical section --------------------------
UMat result;
//bilateralFilter(images.at(i), result, 0, 10, 3);
bilateralFilter(images.at(i), result, 0, i * 10, 3);
#if 0
UMat result;
if (i == 0)
cv::Sobel(images.at(i), result, CV_32F, 1, 0, 5);
else if (i == 1)
cv::Sobel(images.at(i), result, CV_32F, 0, 1, 5);
else
cv::Sobel(images.at(i), result, CV_32F, 1, 1, 5);
#endif
// ------------------------------------------------------------------
chrono::high_resolution_clock::time_point end = chrono::high_resolution_clock::now();
long long ms = chrono::duration_cast<chrono::milliseconds>(end - begin).count();
cout << ms << " ms" << endl;
}
}