Захват кадра с использованием OpenCV в медленном потоке и рендеринг со скоростью экрана в быстром дорогом потоке imgui.C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Захват кадра с использованием OpenCV в медленном потоке и рендеринг со скоростью экрана в быстром дорогом потоке imgui.

Сообщение Anonymous »


Я хотел бы прочитать кадры с камеры, которая работает со скоростью 30 кадров в секунду, обработать их в отдельном потоке и отобразить на экране, используя дорогой графический интерфейс рендеринга imgui с частотой 60 кадров в секунду. Я хотел бы добиться этого, используя методы без блокировки, такие как std::atomic для загрузки (чтение для рендеринга) и хранения (захват с камеры и запись), а также для потоков C++20 jthread. Я сталкиваюсь с ошибками. Я попытался захватить кадры в отдельном потоке и выполнить рендеринг с помощью imgui в основном потоке, и программа просмотра работает со скоростью 60 кадров в секунду, но поток живого видео имеет артефакты и мерцает, вероятно, из-за гонок данных. Я хочу использовать многопоточность без блокировки. Любая помощь будет высоко оценена.

Я попробовал следующее:
#include #include #include #include #include #include #include #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" #если определено(IMGUI_IMPL_OPENGL_ES2) #include #endif #include // #include // OpenCV #include // Атомное логическое значение, позволяющее безопасно остановить поток std::atomic_bool остановлен (ложь); // Функ декабрь void DrawTex(cv::Mat &image, GLuint &image_texture); void Capture(cv::VideoCapture &cap, std::atomic atm_frame_ptr, int &frame_ID); // Основной код int main(int, char **) { glfwSetErrorCallback (glfw_error_callback); если (!glfwInit()) возврат 1; // Создаём окно с графическим контекстом GLFWwindow *window = glfwCreateWindow(1280, 720, "Уважаемый пример ImGui GLFW+OpenGL3", nullptr, nullptr); если (окно == nullptr) возврат 1; glfwMakeContextCurrent (окно); glfwSwapInterval (1); // Включаем вертикальную синхронизацию // Настройка контекста Dear ImGui IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO &io = ImGui::GetIO(); (недействительно) ио; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Включаем управление с клавиатуры io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Включить управление геймпадом // Настройка стиля Dear ImGui ImGui::StyleColorsDark(); // ImGui::StyleColorsLight(); // Настройка платформы/бэкенда рендерера ImGui_ImplGlfw_InitForOpenGL (окно, правда); ImGui_ImplOpenGL3_Init(); // Наше государство bool show_demo_window = правда; bool show_another_window = ложь; ImVec4clear_color = ImVec4(0,45f, 0,55f, 0,60f, 1,00f); // Настройка камеры OpenCV и первый кадр ------ резюме::Матовая рамка; // Атомный общий_ptr std::atomic atm_frame_ptr = std::make_shared(); cv::Mat prev_cvframe, prev_cvframe_gs; cv::Mat current_cvframe, current_cvframe_gs; cv::Mat diff_frame_gs; GLuintframe_tex; GLuintframe_diff_tex; GLuint read_img_tex; // Настраиваем камеру с помощью OpenCV cv::VideoCapture шапка; интервал устройстваID = 0; // 0 = открыть камеру по умолчанию int apiID = cv::CAP_ANY; // 0 = автоопределение API по умолчанию интервал_frame_ID = 0; // счетчик кадров cap.open(deviceID, apiID); cap.read(кадр); std::jthread Capture_thread(Capture, std::ref(cap), atm_frame_ptr, std::ref(frame_ID)); int Frame_ID_GUI = Frame_ID; в то время как (!glfwWindowShouldClose(окно)) { glfwPollEvents(); // Запускаем фрейм Дорогой ImGui ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); // Отображение графического интерфейса // 1. Показ большого демонстрационного окна (Большая часть примера кода находится в ImGui::ShowDemoWindow()! Вы можете просмотреть его код, чтобы узнать больше о Dear ImGui!). если (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window); // 2. Покажем простое окно, которое создаем сами. Мы используем пару Begin/End для создания именованного окна. { ImGui::Begin("GUI"); ImGui::Checkbox("Демо-окно", &show_demo_window); // Редактируем логические значения, хранящие состояние открытия/закрытия нашего окна ImGui::Checkbox("Другое окно", &show_another_window); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Редактируем 1 число с плавающей запятой с помощью ползунка от 0.0f до 1.0f ImGui::ColorEdit3("очистить цвет", (float *)&clear_color); // Редактируем 3 плавающих элемента, представляющих цвет if (ImGui::Button("Button")) // Кнопки возвращают true при нажатии (большинство виджетов возвращают true при редактировании/активации) счетчик++; ImGui::SameLine(); ImGui::Text("counter = %d", counter); ImGui::Text("Среднее значение приложения %.3f мс/кадр (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); ImGui::End(); } // Показать вид с камеры в реальном времени по умолчанию если (cam_window == 1) { DrawTex(frame,frame_tex); ImGui::Begin("Окно камеры", &cam_window); // Передаем указатель на нашу переменную bool (окно будет иметь кнопку закрытия, которая очищает логическое значение при нажатии) ImGui::Text("Идентификатор камеры: 0"); ImGui::Text("Размер изображения = %d x %d",frame.rows,frame.cols); ImGui::Image((void *)(intptr_t)frame_tex, ImVec2(frame.cols,frame.rows)); ImGui::End(); } // Показываем еще одно простое окно. если (show_another_window) { ImGui::Begin("Другое окно", &show_another_window); // Передаем указатель на нашу переменную bool (окно будет иметь кнопку закрытия, которая очищает логическое значение при нажатии) ImGui::Text("Привет из другого окна!"); if (ImGui::Button("Закрыть меня")) show_another_window = ложь; ImGui::End(); } // Рендеринг ImGui::Render(); интервал display_w, display_h; glfwGetFramebufferSize (окно, &display_w, &display_h); glViewport (0, 0, display_w, display_h); glClearColor(clear_color.x *clear_color.w,clear_color.y*clear_color.w,clear_color.z *clear_color.w,clear_color.w); glClear (GL_COLOR_BUFFER_BIT); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers (окно); } // Остановить поток захвата остановлен = правда; крышка.выпуск(); // Очистка ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); glfwDestroyWindow (окно); glfwTerminate(); вернуть 0; } // Соответствие OpenCV текстуре OpenGL void DrawTex(cv::Mat &image, GLuint &image_texture) { если (изображение.пустой()) { std::cout
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»