使用 cython 包装错误级别分析算法的 opencv 实现
Wrapping an opencv implementaion of an error level analysis algorithm using cython
我已经使用 c++(opencv 版本 2.4)实现了错误级别分析算法,我想使用 cython 为它构建一个 python 包装器。
我已经阅读了 cython for c++ 文档的一部分,但它对我没有帮助,而且我没有找到任何额外的在线实现包装器的信息。
如果有人能指导我并帮助我解决这个问题,那就太好了。
这是我要为其构建 pyhton 包装器的代码:
#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
欢迎投稿。
谢谢。
您并不清楚您希望通过此实现什么,但是使这些函数可从 Cython 调用非常容易。首先对 main
进行一些小的更改 - 它需要重命名,以便它不再充当程序的主要功能,并且由于您只使用第二个命令行参数作为文件名,因此您应该更改它至:
void some_function(char* filename) {
// Read the image
input_image = cv::imread(filename);
// everything else the same
}
然后创建您的 Cython 包装器 cy_wrap.pyx
。这有两个部分。首先,您需要告诉 Cython 您的两个 C++ 函数 (cdef extern from
)。其次,您需要编写一个小的包装函数,可以从 Python:
中调用它们
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)
使用此模块,您将能够调用 processImagePy
和 some_functionPy
。
要将其编译为 Python 模块,您需要编写一个 setup.py 文件。我建议你关注 the template given in the Cython documentation (which you have read, right?). Your source files will be cy_wrap.pyx
and ela.cpp
. You'll probably want to link to the OpenCV library. You'll need to specify language="c++"
我已经使用 c++(opencv 版本 2.4)实现了错误级别分析算法,我想使用 cython 为它构建一个 python 包装器。 我已经阅读了 cython for c++ 文档的一部分,但它对我没有帮助,而且我没有找到任何额外的在线实现包装器的信息。 如果有人能指导我并帮助我解决这个问题,那就太好了。
这是我要为其构建 pyhton 包装器的代码:
#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
欢迎投稿。 谢谢。
您并不清楚您希望通过此实现什么,但是使这些函数可从 Cython 调用非常容易。首先对 main
进行一些小的更改 - 它需要重命名,以便它不再充当程序的主要功能,并且由于您只使用第二个命令行参数作为文件名,因此您应该更改它至:
void some_function(char* filename) {
// Read the image
input_image = cv::imread(filename);
// everything else the same
}
然后创建您的 Cython 包装器 cy_wrap.pyx
。这有两个部分。首先,您需要告诉 Cython 您的两个 C++ 函数 (cdef extern from
)。其次,您需要编写一个小的包装函数,可以从 Python:
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)
使用此模块,您将能够调用 processImagePy
和 some_functionPy
。
要将其编译为 Python 模块,您需要编写一个 setup.py 文件。我建议你关注 the template given in the Cython documentation (which you have read, right?). Your source files will be cy_wrap.pyx
and ela.cpp
. You'll probably want to link to the OpenCV library. You'll need to specify language="c++"