2017-12-25 12 views
-1

Ich habe einen Fehler-Level-Analyse-Algorithmus mit C++ (opencv Version 2.4) implementiert und ich möchte einen Python-Wrapper dafür mit Cython erstellen. Ich habe einen Teil der Dokumentation von Cython für C++ gelesen, aber es hat mir nicht geholfen und außerdem habe ich keine zusätzlichen Informationen gefunden, um den Wrapper online zu implementieren. Es wäre wirklich toll, wenn mir jemand helfen und mir helfen könnte, dieses Problem zu lösen.Wrapping einer OpenCV-Implementierung eines Fehler-Level-Analyse-Algorithmus mit Cithon

Dies ist mein Code für die ich einen pyhton Wrapper bauen wollen:

#include <opencv2/highgui/highgui.hpp> 
#include <iostream> 
#include <vector> 

// Control 
int scale = 15, 
quality = 75; 

// Image containers 
cv::Mat input_image, 
compressed_image; 

void processImage(int, void*) 
{ 

// Setting up parameters and JPEG compression 
std::vector<int> parameters; 
parameters.push_back(CV_IMWRITE_JPEG_QUALITY); 
parameters.push_back(quality); 
cv::imwrite("lena.jpeg", input_image, parameters); 

// Reading temp image from the disk 
compressed_image = cv::imread("lena.jpeg"); 

if (compressed_image.empty()) 
{ 
    std::cout << "> Error loading temp image" << std::endl; 
    exit(EXIT_FAILURE); 
} 

cv::Mat output_image = cv::Mat::zeros(input_image.size(), CV_8UC3); 

// Compare values through matrices 
for (int row = 0; row < input_image.rows; ++row) 
{ 
const uchar* ptr_input = input_image.ptr<uchar>(row); 
const uchar* ptr_compressed = compressed_image.ptr<uchar>(row); 
uchar* ptr_out = output_image.ptr<uchar>(row); 

    for (int column = 0; column < input_image.cols; column++) 
    { 
     // Calc abs diff for each color channel multiplying by a scale factor 
     ptr_out[0] = abs(ptr_input[0] - ptr_compressed[0]) * scale; 
     ptr_out[1] = abs(ptr_input[1] - ptr_compressed[1]) * scale; 
     ptr_out[2] = abs(ptr_input[2] - ptr_compressed[2]) * scale; 

     ptr_input += 3; 
     ptr_compressed += 3; 
     ptr_out += 3; 
    } 
} 

// Shows processed image 
cv::imshow("Error Level Analysis", output_image); 
} 

int main (int argc, char* argv[]) 
{ 
// Verifica se o número de parâmetros necessário foi informado 
if (argc < 2) 
{ 
std::cout << "> You need to provide an image as parameter" << std::endl; 
return EXIT_FAILURE; 
} 

// Read the image 
input_image = cv::imread(argv[1]); 

// Check image load 
if (input_image.empty()) 
{ 
    std::cout << "> Error loading input image" << std::endl; 
    return EXIT_FAILURE; 
} 

// Set up window and trackbar 
cv::namedWindow("Error Level Analysis", CV_WINDOW_AUTOSIZE); 
cv::imshow("Error Level Analysis", input_image); 
cv::createTrackbar("Scale", "Error Level Analysis", &scale, 100, processImage); 
cv::createTrackbar("Quality", "Error Level Analysis", &quality, 100, processImage); 

// Press 'q' to quit 
while (char(cv::waitKey(0)) != 'q') {}; 

return EXIT_SUCCESS; 
} 

https://github.com/shreyneil/image_test/blob/master/ela.cpp

Beiträge sind willkommen. Danke.

+0

Ich denke, Sie müssen im Detail darüber nachdenken, was Sie wollen: nach Ihrem Github haben Sie eine Funktion, die beide Parameter ignoriert und nichts zurückgibt - das sieht nicht so aus, als könnte es sinnvoll verpackt werden in Cython. Sie haben auch ein Hauptprogramm, das einige Dateinamen als Befehlszeilenargumente akzeptiert und opencv aufruft - was wiederum nicht wirklich ein guter Kandidat ist, um sich in Cython einzubinden. Sie haben den Code auch offline gestellt, sodass es sich hier nicht um eine eigenständige Frage handelt. Endlich gibt es bereits einen opencv-Wrapper für Python? Warum nicht das benutzen? – DavidW

+0

Sir, mit Cython ist Teil der Aufgabe für mich und ist eine Notwendigkeit, um es abzuschließen. Ich bin neu in Cython, also wäre es wirklich toll, wenn Sie mich durch das Einbinden des oben genannten Codes mit Cython führen könnten, wie zB in welche Klassen die Wrapped-Klasse eingebunden wird und andere relevante Dinge. Vielen Dank. –

Antwort

1

Es ist nicht wirklich klar, was Sie damit erreichen wollen, aber es ist ziemlich einfach, die Funktionen von Cython aufrufbar zu machen. Beginnen Sie mit kleinen Änderungen an main - es muss umbenannt werden, damit es nicht mehr als Hauptfunktion für ein Programm fungiert, und da Sie nur das zweite Befehlszeilenargument als Dateinamen verwenden, sollten Sie es wie folgt ändern:

void some_function(char* filename) { 
    // Read the image 
    input_image = cv::imread(filename); 
    // everything else the same 
} 

Dann erstellen Sie Ihre Cython-Wrapper cy_wrap.pyx. Es gibt zwei Teile davon. Zuerst müssen Sie Cython über Ihre beiden C++ - Funktionen (cdef extern from) informieren. Zweitens benötigen Sie einen kleinen Wrapper-Funktion zu schreiben, die diese aus Python anrufen:

cdef extern from "ela.hpp": 
    # you'll need to create ela.hpp with declarations for your two functions 
    void processImage(int, void*) 
    void some_function(char* filename) 

# and Python wrappers 
def processImagePy(): 
    # since the parameters are ignored in C++ we can pass anything 
    processImage(0,NULL) 

def some_functionPy(filename): 
    # automatic conversion from string to char* 
    some_function(filename) 

Mit diesem Modul Sie werden in der Lage sein processImagePy und some_functionPy zu nennen.

Um es zu einem Python-Modul zu kompilieren, müssen Sie eine setup.py-Datei schreiben. Ich schlage vor, Sie folgen the template given in the Cython documentation (die Sie gelesen haben, oder?). Ihre Quelldateien sind cy_wrap.pyx und ela.cpp. Wahrscheinlich möchten Sie mit der OpenCV-Bibliothek verlinken. Sie müssen specify language="c++"

+0

Vielen Dank, ich konnte [die Wrapper] (https://github.com/shreyneil/image_test) -Klasse für mein Programm mit Cython bauen, aber während der Zeit des Testens bekomme ich den folgenden Fehler: ImportError:/home/shreyash/Desktop/Neu/ela_c.so: undefined symbol: _ZN2cv14createTrackbarERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIceeES7_PiiPFvpvES9_ –

+0

Das sieht wie ein Teil von OpenCV aus. Sie müssen möglicherweise ändern, was in 'Bibliotheken' ist. Ich habe nie OpenCV verwendet, also kann ich nicht wirklich helfen – DavidW

+0

Sir, Danke für Ihre Hilfe, aber ich denke, ich bin nicht in der Lage, die gemeinsame Objektdatei mit Python zu verknüpfen, und deshalb bekomme ich einige Fehler. Können Sie bitte die notwendigen Schritte dazu machen? Es wäre wirklich hilfreich. Vielen Dank. –