2017-09-18 12 views
-1

먼저 다음을 수행하십시오. OpenCV C++를 사용하여 이미지 처리 작업을하고 있습니다. C++ 프로그램에서 매트 이미지를로드 한 후 GNUPLOT을 사용하여 이미지의 그래프를 그렸다.OpenCV/BOOST에서 그래픽 데이터를 로그하는 방법을 찾으려고 시도

이제 요구 사항은 매트 이미지의 그래픽 데이터를 기록하는 것입니다.

이렇게하려면, 나는 모든 BOOST 라이브러리를 포함시켜 BOOST C++ Logger를 만들었습니다. BOOST는 데이터 테스트 및 로깅을위한 훌륭한 라이브러리이지만 로그의 문제점은 텍스트 메시지 만 기록 할 수 있다는 것입니다. 틀 렸으면 고쳐줘. 다음은

는 OpenCV의에 의 gnuplot을 사용하여, 그래프 내 코드입니다 : 좋은 소식은
namespace logging = boost::log; 
void PlainGetEdgeVector::init() 
{ 

logging::add_file_log("sample%3N.log"); 

} 

BOOST_LOG_TRIVIAL(info) << "This is my first Log line"; 

입니다

, 내 BOOST 로거 성공적으로 : 여기

try 
{ 
    Gnuplot g1("lines"); 

    std::vector<double> rowVector; 
    std::vector<double> rowVectorExp; 

    for (int i = 0; i < 50; i++) 
    { 
     rowVector.push_back((double)i); 
     rowVectorExp.push_back((double)exp((float)i/10.0)); 

    } 
    cout << "*** user-defined lists of doubles" << endl; 
    g1 << "set term png"; 
    g1 << "set output \"test.png\""; 

    //type of plot pattern 
    g1.set_grid().set_style("lines"); 

    g1.plot_xy(rowVector, rowVectorExp, "user-defined points 2d"); 

    waitKey(0); 
} 
catch (GnuplotException ge) 
{ 
    cout << ge.what() << endl; 
} 

cout << endl << "*** end of gnuplot example" << endl; 

BOOST 로그 코드입니다 텍스트 메시지를 기록합니다. 그래픽 데이터를 기록 할 수 있다면 좋을 것입니다.

제안 사항? 누구든지 BOOST를 사용하여 동일한 기능을 구현하는 방법을 알고 있다면 매우 감사 할 것입니다.

답변

1

로그 된 데이터를 어떻게 사용 하시겠습니까? 데이터의 특성에 따라 솔루션이 크게 달라집니다.

1. 종종 텍스트로 바이너리 데이터를 변환하는 것이 더 편리 디버깅 목적

을 텍스트로 바이너리 데이터를 변환 다시 고려한다. 많은 양의 데이터가 있더라도이 방법은 일반적으로 임의의 이진 데이터로 작업하는 것보다 텍스트 처리를위한 도구가 훨씬 많기 때문에 유용 할 수 있습니다. 예를 들어, 응용 프로그램의 여러 실행에서 얻은 두 로그를 기존 병합/비교 도구로 비교하여 차이점을 확인할 수 있습니다. 텍스트 로그는 grep 또는 awk과 같은 도구를 사용하여 쉽게 필터링 할 수 있습니다.이 도구는 파서를 작성해야 할 가능성이있는 바이너리 데이터와 달리 쉽게 사용할 수 있습니다.

바이너리 데이터를 텍스트로 변환하는 많은 방법이 있습니다. 가장 직접적인 접근 방식은 dump 매니퓰레이터를 사용하는 것인데, 이는 원시 바이너리 데이터의 텍스트보기를 효율적으로 생성합니다. 비교적 많은 양의 경향이 있고 텍스트 표현 (예 : 색상 샘플이 1 바이트에 맞을 때)에서 비교하기가 쉽기 때문에 그래픽 데이터에도 적합합니다.

std::vector<std::uint8_t> image; 
// Outputs hex dump of the image 
BOOST_LOG_TRIVIAL(info) << logging::dump(image.data(), image.size()); 

출력 이진 데이터에 더 구조화 된 방식은 Boost.Range에서 iterator_range 다른 라이브러리를 사용하는 것이다. 그래픽 데이터가 원시 바이트보다 복잡한 것으로 구성된 경우 유용 할 수 있습니다.

std::vector<double> image; 
// Outputs all elements of the image vector 
BOOST_LOG_TRIVIAL(info) << boost::make_iterator_range(image); 

데이터를 원하는대로 포맷하는 고유 한 조작기를 작성할 수도 있습니다. 출력을 행별로 나눕니다.

2.이진 데이터 사용 특성 및 사용자 지정 싱크 백엔드의 경우

로깅 된 데이터를 이미지 뷰어 나 편집기와 같이 특수화 된 소프트웨어로 처리하려는 경우 이진 형식으로 데이터를 저장해야 할 수 있습니다. Boost.Log를 사용하면이 작업을 수행 할 수 있지만 라이브러리에서 제공하는 싱크가 텍스트 기반이며 바이너리 데이터를 그대로 텍스트 파일에 저장할 수 없기 때문에 더 많은 노력이 필요합니다. 싱크 백엔드을 작성하여 원하는 형식으로 이진 데이터를 작성해야합니다 (예 : 이미지 편집기를 사용하려는 경우 해당 편집기에서 지원하는 형식으로 파일을 쓸 수 있음). 튜토리얼 here은 구현해야하는 인터페이스와 샘플 구현을 보여줍니다. 중요한 비트는 백엔드의 consume 기능이며 데이터와 함께 로그 레코드보기를 수신합니다.

typedef boost::iterator_range< const double* > image_data; 
BOOST_LOG_ATTRIBUTE_KEYWORD(a_image, "Image", image_data) 

class image_writer_backend : 
    public sinks::basic_sink_backend<sinks::synchronized_feeding> 
{ 
public: 
    void consume(logging::record_view const& rec) 
    { 
     // Extract the image data from the log record 
     if (auto image = rec[a_image]) 
     { 
      image_data const& im = image.get(); 

      // Write the image data to a file 
     } 
    } 
}; 

이미지 바이너리 데이터를 싱크대로 전달하려면 로그 레코드에 속성으로 첨부해야합니다. 이를 수행하는 방법은 여러 가지가 있지만 이미지를 기반으로 로그 레코드를 필터링하지 않는다고 가정하면 가장 쉬운 방법은 add_value 매니퓰레이터를 사용하는 것입니다.

std::vector<double> image; 
BOOST_LOG_TRIVIAL(info) << logging::add_value(a_image, image) << "Catch my image"; 

경고 : 잠재적으로 큰 이미지 데이터를 복사하는 것을 방지하기 위해, 우리는 속성 값으로 경량 iterator_range을 전달하고 있습니다. 로그 레코드가 처리되는 동안 image 벡터가 활성 상태를 유지해야하므로 동기 로깅에서만 작동합니다. 비동기 로깅의 경우 값으로 이미지를 전달하거나 참조 카운팅을 사용해야합니다.

이미지 데이터에 필터를 적용하려면 scoped attributes을 사용하거나 logger에 속성을 추가하십시오.

새 싱크를 추가하여 이진 데이터를 쓰면 텍스트 싱크가 "내 이미지 잡기"메시지를 처리 ​​할 수 ​​있도록 다른 싱크와 함께 텍스트 로그를 쓰는 것을 배제하지 않습니다. 로그 레코드 counters과 같은 다른 속성을 사용하면 다른 싱크에서 생성 된 서로 다른 파일의 로그 레코드를 연결할 수 있습니다.