129 / 17 / 5
Регистрация: 23.03.2020
Сообщений: 103
1

Python c opencv использующий dll с cpp и opencv через ctypes и пустые окна

30.01.2024, 20:09. Показов 1228. Ответов 4

Author24 — интернет-сервис помощи студентам
Возможно мне стоило писать в тред по питону, заранее прошу прощения если ошибся.

У меня есть dll написанная на cpp, вот ее код
Header:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#ifndef PyInterH
 
#include <Eigen/Cholesky>
#include <svo/config.h>
#include <svo/frame_handler_mono.h>
#include <svo/map.h>
#include <svo/frame.h>
#include <vector>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/core/eigen.hpp>
#include <sophus/se3.hpp>
#include <iostream>
 
#include <svo/camera_model.h>
 
class PythonInterface
{
    svo::AbstractCamera* cam_;
    svo::FrameHandlerMono* vo_;
    int img_id = 0;
    float RTthing[6] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
 
public:
    PythonInterface() {};
    ~PythonInterface();
    void Init(int screenx, int screeny, int focal);
    void Update(cv::Mat image);
    float* GetActualRT();
};
 
#ifdef __cplusplus
extern "C" {
#endif
 
    __declspec(dllexport) PythonInterface* PythonInterface_new();//
    __declspec(dllexport) void PythonInterface_del(PythonInterface* pyinter);//
    __declspec(dllexport) void PythonInterface_init(PythonInterface* pyinter, int scrx, int scry, int focal);//
    __declspec(dllexport) void PythonInterface_update(PythonInterface* pyinter, double* matrix, int row, int col);
    __declspec(dllexport) float* PythonInterface_getactualrt(PythonInterface* pyinter);
 
#ifdef __cplusplus
}
#endif
#endif
CPP:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <Eigen/Cholesky>
#include <svo/config.h>
#include <svo/frame_handler_mono.h>
#include <svo/map.h>
#include <svo/frame.h>
#include <vector>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/core/eigen.hpp>
#include <sophus/se3.hpp>
#include <iostream>
 
#include <svo/camera_model.h>
 
#include "PyInter.h"
 
void PythonInterface::Init(int screenx, int screeny, int focal)
{
    cam_ = new svo::PinholeCamera(
        screenx, screeny,
        focal, focal,
        screenx / 2, screeny / 2,
        0, 0, 0, 0, 0);
 
    vo_ = new svo::FrameHandlerMono(cam_);
    vo_->start();
    cv::setNumThreads(0);
}
 
void PythonInterface::Update(cv::Mat image)
{
    img_id++;
    if (img_id < 0) return;
    //std::cout << img_id << std::endl;
    cv::imshow("origin_image", image);
    cv::waitKey(1);
    std::cout << image.empty() << std::endl;
    //vo_->addImage(image, 0.01 * img_id);
    cv::waitKey(1);
}
 
float* PythonInterface::GetActualRT()
{
    for (int i = 0; i < 6; i++) RTthing[i] = 0.0f;
    if (vo_->lastFrame() != NULL)
    {
        auto tfw = vo_->lastFrame()->T_f_w_;
        auto R = tfw.rotationMatrix();
        auto t = tfw.translation();
        cv::Mat Rmat, rvec, tvec;
        cv::eigen2cv(R, Rmat);
        cv::eigen2cv(t, tvec);
        cv::Rodrigues(Rmat, rvec);
        for (int i = 0; i < 3; i++) RTthing[i] = tvec.at<double>(i, 0);
        for (int i = 0; i < 3; i++) RTthing[i + 3] = rvec.at<double>(i, 0);
    }
    return RTthing;
}
 
PythonInterface::~PythonInterface()
{
    delete vo_;
    delete cam_;
}
 
 
/* $$$ ОБЕРТКИ $$$ */
 
PythonInterface* PythonInterface_new()
{
    return new PythonInterface();
}
 
void PythonInterface_del(PythonInterface* pyinter)
{
    delete pyinter;
}
 
void PythonInterface_init(PythonInterface* pyinter, int scrx, int scry, int focal)
{
    pyinter->Init(scrx, scry, focal);
}
 
void PythonInterface_update(PythonInterface* pyinter, double* matrix, int row, int col)
{
    //cv::Mat mat = cv::Mat(row, col, CV_64F, matrix);
    //mat = mat.clone();
    //std::cout << matrix << std::endl;
    //std::cout << reinterpret_cast<void*>(mat.data) << std::endl;
    cv::Mat mat = cv::imread("gos.jpg"), gray;
    std::cout << "HELLO FROM CPP " << mat.cols << " " << mat.rows << " " << std::endl;
    cv::cvtColor(mat, gray, cv::COLOR_BGR2GRAY);
    cv::waitKey(1);
    pyinter->Update(gray);
}
 
float* PythonInterface_getactualrt(PythonInterface* pyinter)
{
    return pyinter->GetActualRT();
}
DLL должна будет давать интерфейс к одной библиотеке, но я не думаю что дело в ней, поэтому неважно.

У меня есть код на python, представленный ниже
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import cv2 as cv
import ctypes
import numpy as np
import numpy.ctypeslib as npct
 
# Загрузка библиотеки
svocpp = ctypes.windll.LoadLibrary('./DLLExp3.dll')
 
svocpp.PythonInterface_new.restype = ctypes.c_void_p
 
svocpp.PythonInterface_init.restype = ctypes.c_void_p
svocpp.PythonInterface_init.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int]
 
array_1d_int = npct.ndpointer(dtype=float, ndim=1, flags='CONTIGUOUS')
svocpp.PythonInterface_update.restype = ctypes.c_void_p
svocpp.PythonInterface_update.argtypes = \
    [ctypes.c_void_p, array_1d_int, ctypes.c_int, ctypes.c_int]
 
svocpp.PythonInterface_getactualrt.restype = npct.ndpointer(dtype=ctypes.c_float, shape=(6,))
svocpp.PythonInterface_getactualrt.argtypes = [ctypes.c_void_p]
 
svocpp.PythonInterface_del.restype = ctypes.c_void_p
svocpp.PythonInterface_del.argtypes = [ctypes.c_void_p]
 
svocppobj = svocpp.PythonInterface_new()
 
svocpp.PythonInterface_init(svocppobj, 640, 480, 977)
 
cv.waitKey(1000)
 
print("Starting")
 
#cap = cv.VideoCapture(0)
 
#if not cap.isOpened():
#    print("Cap isn't opened")
 
gray = cv.imread("gos1.jpg", cv.IMREAD_GRAYSCALE)
height, width = gray.shape[:2]
x = np.divide(gray, (255)).ravel()
cv.imshow("1", gray)
cv.waitKey(1)
svocpp.PythonInterface_update(svocppobj, x, height, width)
cv.waitKey(1)
 
print("Ending")
 
svocpp.PythonInterface_del(svocppobj)
В чем собственно проблема.
Мне нужно будет кидать картинку из питона в плюсы. В процессе происходило непотребство, поэтому я упростил задачу до того, что питон у себя сам читает и выводит свою картинку, а плюсы читают и пока что просто выводят свою картинку, и тут начинается проблема с которой мне нужна помощь. В том виде в котором код представлен выше питон штатно выводит Райана Гослинга, а плюсы выводят пустое окошко, причем правильного размера. Если я закомменчу в питоне 42 строчку, а именно эту:
Python
1
cv.imshow("1", gray)
То плюсы выводят картинку правильно и без проблем.
Собственно первый и единственный вопрос. Почему?
Я читал в инете, и похожая ошибка была у людей, когда они не ставили waitkey после imshow, и там что-то типо того что opencv не успевает обработать событие вывода картинки в окно. У меня стойкое ощущение что я что-то делаю не так, простите если вопрос глупый, помогите пожалуйста
Миниатюры
Python c opencv использующий dll с cpp и opencv через ctypes и пустые окна   Python c opencv использующий dll с cpp и opencv через ctypes и пустые окна  
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.01.2024, 20:09
Ответы с готовыми решениями:

OpenCV kmeans.cpp из opencv249\sources\samples\cpp
#include &quot;opencv2/highgui/highgui.hpp&quot; #include &quot;opencv2/core/core.hpp&quot; #include &lt;iostream&gt; ...

Opencv Dev-Cpp
Ошибка: &quot;Source file not compiled&quot; #include &lt;opencv2/opencv.hpp&gt; #include &lt;iostream&gt; using...

Opencv error the function/feature is not implemented (opencv was built without surf support)
Недавно настроила OpenCV для CodeBlocks, однако первый пример поиска плоских объектов с помощью...

Лабораторная bag-of-words image classification OpenCV 2.4 в OpenCV 3
Здравствуйте! Делал лабораторную с интуита по OpenCV, но там она для старой версии, а мне нужно в...

Помощь с нейросеткой с opencv. Error in module: Name 'opencv' is not defined
Ребят, привет. Признаюсь честно, я начинающий программист, и делал раньше в основном простые...

4
207 / 100 / 20
Регистрация: 30.06.2020
Сообщений: 848
31.01.2024, 21:31 2
Цитата Сообщение от Hacker_Den Посмотреть сообщение
а плюсы выводят пустое окошко
cv::waitKey(0); после вывода. Или 1 или 0

Добавлено через 48 секунд
Хотя стоит это всё дело, странно
0
129 / 17 / 5
Регистрация: 23.03.2020
Сообщений: 103
01.02.2024, 16:10  [ТС] 3
Проблема упростилась
Подключил ту же dll из других плюсов, ничего не изменилось, dll выводит серый экран
При том что перед этим просто функция без класса выводила картинку вроде бы нормально
Возможно я что-то напортачил с ООП
0
207 / 100 / 20
Регистрация: 30.06.2020
Сообщений: 848
02.02.2024, 01:59 4
Лучший ответ Сообщение было отмечено Hacker_Den как решение

Решение

Цитата Сообщение от Hacker_Den Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
void PythonInterface_update(PythonInterface* pyinter, double* matrix, int row, int col)
{
    //cv::Mat mat = cv::Mat(row, col, CV_64F, matrix);
    //mat = mat.clone();
    //std::cout << matrix << std::endl;
    //std::cout << reinterpret_cast<void*>(mat.data) << std::endl;
    cv::Mat mat = cv::imread("gos.jpg"), gray;
    std::cout << "HELLO FROM CPP " << mat.cols << " " << mat.rows << " " << std::endl;
    cv::cvtColor(mat, gray, cv::COLOR_BGR2GRAY);
    cv::waitKey(1);
    pyinter->Update(gray);
}
А вот здесь если убрать перевод в серый формат - выводится изображение?

Добавлено через 1 час 47 минут
Цитата Сообщение от Hacker_Den Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
void PythonInterface::Update(cv::Mat image)
{
    img_id++;
    if (img_id < 0) return;
    //std::cout << img_id << std::endl;
    cv::imshow("origin_image", image);
    cv::waitKey(1);
    std::cout << image.empty() << std::endl;
    //vo_->addImage(image, 0.01 * img_id);
    cv::waitKey(1);
}
А потом попробуйте убрать проверку img_id если не сработает. Не совсем даже понимаю на кой черт оно тут нужно, если у вас просто вывод изображения

Добавлено через 4 минуты
Цитата Сообщение от Hacker_Den Посмотреть сообщение
Если я закомменчу в питоне 42 строчку
Ну и третий вариант уже здесь - если что-то используете - то используйте или через обертку, или в сыром виде. Вызывая показ изображения скорее всего случается конфликт, ибо по сути это из разных языков вызов одного и того же и может ченть ломаться (бывает и такое). Попробуйте в варианте с темы подёргать вывод изображения только через вашу Си обёртку. Если всё гуд - то конфликт случился (почему и как эт надо глубже копать, может конкретно ваша среда разработки такие приколы при мультиязычности даёт, может потому что Си компилируемый, а Питон интерпретируемый и нельзя дергать OpenCV и так и сяк в рамках одного проекта (или файла)). Пока что больше идей нет, проверьте эти
0
129 / 17 / 5
Регистрация: 23.03.2020
Сообщений: 103
17.02.2024, 13:58  [ТС] 5
Проблема решилась
Только я не уверен что именно помогло
Полагаю, что дело в том, что я начал передавать картинку как массив c_ubyte и возможно потому что начал подгружать dll через ctypes.CDLL()
0
17.02.2024, 13:58
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.02.2024, 13:58
Помогаю со студенческими работами здесь

OpenCV dll
Здравствуйте. Появилась необходимость работать с OpenCV на Питоне (версия 3+). В общем, есть...

OpenCV Python
Начал только изучать библиотеку OpenCV для Python пытаюсь вывести изображение с камеры с помощью...

Python OpenCV
Здравствуйте! Решил выбрать для проектной деятельности в 10 классе работу с OpenCV на Python. Такая...

OpenCV, QT C++ и Python
Приветствую, товарищи. У меня есть почти готовый проект в КьюТи, написанный на С++. Проект...

Python + OpenCV
Добрый день! Дали задачу по компьютерному зрению, но никак не могу в ней разобраться. Вот сама...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru