2013-11-13 5 views

ответ

2

Вот краткий пример каир + OpenCV использования, надеюсь, это будет Userful:

#include <iostream> 
#include <vector> 
#include <stdio.h> 
#include "opencv2/opencv.hpp" 

#include "cairo/cairo-win32.h" 
#include "cairo/cairo-pdf.h" 
#include "cairo/cairo-ps.h" 
#include "cairo/cairo-svg.h" 
using namespace std; 
using namespace cv; 
//----------------------------------------------------------------------------------------------------- 
// 
//----------------------------------------------------------------------------------------------------- 
void MatToCairo(Mat &MC3,cairo_surface_t *surface) 
{ 
     Mat MC4 = Mat(cairo_image_surface_get_width(surface),cairo_image_surface_get_height(surface),CV_8UC4,cairo_image_surface_get_data(surface),cairo_image_surface_get_stride(surface)); 
     vector<Mat> Imgs1; 
     vector<Mat> Imgs2; 
     cv::split(MC4,Imgs1); 
     cv::split(MC3,Imgs2); 
     for(int i=0;i<3;i++) 
     { 
     Imgs1[i]=Imgs2[i]; 
     } 
     // Alpha - прозрачность 
     Imgs1[3]=255; 
     cv::merge(Imgs1,MC4); 
} 
//----------------------------------------------------------------------------------------------------- 
// 
//----------------------------------------------------------------------------------------------------- 
void CairoToMat(cairo_surface_t *surface,Mat &MC3) 
{ 
     Mat MC4 = Mat(cairo_image_surface_get_width(surface),cairo_image_surface_get_height(surface),CV_8UC4,cairo_image_surface_get_data(surface),cairo_image_surface_get_stride(surface)); 
     vector<Mat> Imgs1; 
     vector<Mat> Imgs2; 
     cv::split(MC4,Imgs1); 
     cv::split(MC3,Imgs2); 
     for(int i=0;i<3;i++) 
     { 
     Imgs2[i]=Imgs1[i]; 
     } 
     cv::merge(Imgs2,MC3); 
} 
//----------------------------------------------------------------------------------------------------- 
// 
//----------------------------------------------------------------------------------------------------- 
int main(int argc, char** argv) 
{ 
    int m_spcount; 
    double m_compactness(0); 
    int width; 
    int height; 
    Mat Img=imread("D:\\ImagesForTest\\lena.jpg"); 
    namedWindow("Image"); 
    width=Img.cols; 
    height=Img.rows; 

     cairo_surface_t *surface; 
     cairo_t *cr; 
     surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); 
     cr = cairo_create(surface); 

     MatToCairo(Img,surface); 

     cairo_select_font_face (cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); 
     cairo_set_font_size (cr, 32.0); 
     cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); 
     cairo_move_to (cr, 10.0, 50.0); 
     cairo_show_text (cr, "Hello, world"); 

     cairo_surface_write_to_png (surface, "hello.png"); 

     CairoToMat(surface,Img); 

     imshow("Image", Img); 

     waitKey(0); 
     cairo_destroy (cr); 
     cairo_surface_destroy (surface); 
     destroyAllWindows(); 
    return 0; 
} 
+0

Благодарю вас, господин Смородова. Я думаю, что ваш ответ прав. но когда код достигает 'cv :: split (MC4, Imgs1);' в функции cairoToMat делает ошибку сегментации. Почему у меня есть эта проблема? –

+0

Просто добавил незначительные исправления и протестировал его, он отлично работает для меня. Я использую здесь двоичные файлы cairo, заголовки и библиотеки (для win7x64): http://www.gtk.org/download/win64.php Вам также нужны дополнительные dll с этого сайта и поместите их на путь exe. Также убедитесь, что ваше изображение загружено правильно. –

1

Я использую cairomm, С ++ оберткой Каира, вместо Каира, но вещи должны быть одинаковыми. После выделения памяти для opencv Mat просто скопируйте память с поверхности каира на Mat и это сработает.

#include <opencv2/opencv.hpp> 
#include <cairommconfig.h> 
#include <cairomm/context.h> 
#include <cairomm/surface.h> 

int main() 
{ 
    Cairo::RefPtr<Cairo::ImageSurface> surface = 
     Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 600, 400); 

    Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface); 

    cr->save(); // save the state of the context 
    cr->set_source_rgb(0.86, 0.85, 0.47); 
    cr->paint(); // fill image with the color 
    cr->restore(); // color is back to black now 

    cr->save(); 
    // draw a border around the image 
    cr->set_line_width(20.0); // make the line wider 
    cr->rectangle(0.0, 0.0, surface->get_width(), surface->get_height()); 
    cr->stroke(); 

    cr->set_source_rgba(0.0, 0.0, 0.0, 0.7); 
    // draw a circle in the center of the image 
    cr->arc(surface->get_width()/2.0, surface->get_height()/2.0, surface->get_height()/4.0, 0.0, 2.0 * M_PI); 
    cr->stroke(); 

    // draw a diagonal line 
    cr->move_to(surface->get_width()/4.0, surface->get_height()/4.0); 
    cr->line_to(surface->get_width() * 3.0/4.0, surface->get_height() * 3.0/4.0); 
    cr->stroke(); 
    cr->restore(); 

    cv::Mat m(surface->get_height(), surface->get_width(), CV_8UC4); 
    memcpy(m.data, surface->get_data(), 4 * surface->get_width() * surface->get_height()); 

    cv::imshow("cairo", m); 
    cv::waitKey(0); 
} 

Смежные вопросы