2016-07-19 2 views
0

here은 LibTIFF가 부동 소수점 TIFF를 표시 할 수 있다고 읽었습니다. 그러나 이미지를로드하고 float 값을 배열로 가져 오려고합니다.C++에서 LibTIFF를 사용하여 이미지의 실수 값을 가져올 수 있습니까?

LibTIFF를 사용하면 가능합니까?

편집 : RHEL 6을 사용하고

편집 : 잘못된 링크에 대한 https://www.dropbox.com/s/f15fkkj5dg5ojzt/map.tif?dl=0

죄송합니다!

예제 TIFF에 대한 링크.

+0

내 대답 또는 다른 문제가 귀하의 문제를 정리 했습니까? 그렇다면 투표 수 옆의 빈 녹색 체크/체크 표시를 클릭하여 답변으로 수락하십시오. 그렇지 않은 경우, 나 또는 다른 누군가가 귀하를 더 멀리 도울 수 있도록 작동하지 않은 것을 말하십시오. 감사. http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235 –

+0

'Dropbox '를 사용하여 TIFF에 대한 링크를 공유하거나 Microsoft의'OneDrive '또는 'Imgur' 또는 somesuch. –

+0

뷰어에 관해서는 ImageMagick의 일부인'gimp','feh' 또는'display'를 시도 할 수 있습니다. –

답변

1

, 당신의 코드를 다음과 같이 보일 수 있습니다 - 나는의 독자를 혼동하지 않도록 확인 많은 오류를하지 않은 점에 유의 code -하지만 이미지가 float 유형인지 확인해야하고 메모리 할당 결과를 확인해야하며 malloc()을 사용하는 것이 아니라 새로운 C++ 메모리 할당 방법을 사용해야합니다. 개념은 분명히 명확합니다. 코드는 내 CImg 버전과 동일한 대답을 생성합니다 ...

#include "tiffio.h" 
#include <cstdio> 
#include <iostream> 

using namespace std; 

int main() 
{ 

    TIFF* tiff = TIFFOpen("image.tif","r"); 
    if (!tiff) { 
    cerr << "Failed to open image" << endl; 
    exit(1); 
    } 

    uint32 width, height; 
    tsize_t scanlength; 

    // Read dimensions of image 
    if (TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH,&width) != 1) { 
    cerr << "Failed to read width" << endl; 
    exit(1); 
    } 
    if (TIFFGetField(tiff,TIFFTAG_IMAGELENGTH, &height) != 1) { 
    cerr << "Failed to read height" << endl; 
    exit(1); 
    } 

    scanlength = TIFFScanlineSize(tiff); 

    // Make space for image in memory 
    float** image= (float**)malloc(sizeof (float*)*height); 

    cout << "Dimensions: " << width << "x" << height << endl; 
    cout << "Line buffer length (bytes): " << scanlength << endl; 

    // Read image data allocating space for each line as we get it 
    for (uint32 y = 0; y < height; y++) { 
    image[y]=(float*)malloc(scanlength); 
    TIFFReadScanline(tiff,image[y],y); 
    cout << "Line(" << y << "): " << image[y][0] << "," << image[y][1] << "," << image[y][2] << endl; 
    } 
    TIFFClose(tiff); 

} 

샘플 출력은 다음과 같이 내가 명령 줄에서 터미널에서 ImageMagick를 사용하여 일반 JPEG로 이미지를 변환

그런데

Dimensions: 512x256 
Line buffer length (bytes): 6144 
Line(0): 3.91318e-06,0.232721,128 
Line(1): 0.24209,1.06866,128 
Line(2): 0.185419,2.45852,128 
Line(3): 0.141297,3.06488,128 
Line(4): 0.346642,4.35358,128 
... 
... 

... :

convert map.tif[0] -auto-level result.jpg 

enter image description here

+0

모든 솔루션을 제공해 주셔서 감사합니다. 나는 이것이 효과가있을 것이라고 생각한다. 우선 빠른 질문이 있습니다. 어떻게하면 TIFF 이미지를 먼저 볼 수 있습니까? 필자는 문서를 읽었지만 단지 이미지를보기보다는 데이터를 얻는 방법을 찾고 있습니다. 참고로 LibGeoTIFF를 사용하고 있습니다. – user8333141

+0

즐거움! 샘플 이미지를 제공해 주시면 도움이 될 것입니다. 또한 사용하는 운영 체제도 알려주십시오. 만약 할당의 새로운 방법을 말할 때, 원하는 말이야 –

+0

'떠 ** 이미지 = 부동 소수점 * 높이]'는 '위해 (나는은 높이 <; I = 0 값 int ++ I) 화상 [I] = 새로운 float [폭]; – user8333141

0

예.하지만 OpenCV 라이브러리를 사용하면 훨씬 쉽게 시간을 가질 수 있습니다.

OpenCV 라이브러리를 컴파일하고 설치하면 묻는대로 imread() 기능을 사용하는 것만 큼 쉽습니다. 이렇게하면 tiff와 ​​동일한 크기와 값을 가진 cv :: Mat (일명 매트릭스)라는 객체에 저장됩니다.

거기에서 원하는대로 할 수 있습니다.

1

당신 LibTIFF 함께 할, 내가 아니라 나중에 기반으로 대답을 추가 할 수 있지만, 설치 및 사용의 용이성을 위해, 내가하는 C++ 헤더 전용 라이브러리 인 CImg 볼 것 귀하의 목적에 매우 강력하고 이상적입니다. 헤더 전용이므로 포함 (하나의 파일)하기가 쉽고 특별한 연결이나 건물이 필요하지 않습니다. 여기

는 RGB의 TIFF 수레 읽을 수있는 방법은 다음과 같습니다

그들은 평면으로 배열되어 있기 때문에 처음 세 개의 빨간 픽셀을 출력
#define cimg_display 0 
#define cimg_use_tiff 
#include "CImg.h" 
#include <iostream> 

using namespace cimg_library; 
using namespace std; 

int main(){ 

    // Read in an image 
    CImg <float>img("image.tif"); 

    // Get its width and height and tell user 
    int w=img.width(); 
    int h=img.height(); 
    cout << "Dimensions: " << w << "x" << h << endl; 

    // Get pointer to buffer/array of floats 
    float* buffer = img.data(); 

    cout << buffer[0] << "," << buffer[1] << "," << buffer[2] << endl; 
} 

- 즉, 모든 적색 픽셀 첫째, 모든 녹색 픽셀 다음 모든 파란색 픽셀. 원하는 경우

g++-6 -std=c++11 read.cpp -I/usr/local/include -L/usr/local/lib -ltiff -o read 

, 당신은 약간 다른 방식으로 같은 픽셀에 액세스 할 수 있습니다 : 함께

당신은 컴파일 할

#define cimg_display 0 
#define cimg_use_tiff 
#include "CImg.h" 
#include <iostream> 

using namespace cimg_library; 
using namespace std; 

int main(){ 

    // Read in an image 
    CImg <float>img("image.tif"); 

    // Get its width and height and tell user 
    int w=img.width(); 
    int h=img.height(); 
    cout << "Dimensions: " << w << "x" << h << endl; 

    // Dump the pixels 
    for(int y=0;y<h;y++) 
     for(int x=0;x<w;x++) 
      cout << x << "," << y << ": " 
       << img(x,y,0,0) << "/" 
       << img(x,y,0,1) << "/" 
       << img(x,y,0,2) << endl; 

} 

샘플 출력

Dimensions: 512x256 
0,0: 3.91318e-06/0.232721/128 
1,0: 1.06577/0.342173/128 
2,0: 2.3778/0.405881/128 
3,0: 3.22933/0.137184/128 
4,0: 4.26638/0.152943/128 
5,0: 5.10948/0.00773837/128 
6,0: 6.02352/0.058757/128 
7,0: 7.33943/0.02835/128 
8,0: 8.33965/0.478541/128 
9,0: 9.46735/0.335981/128 
10,0: 10.1918/0.340277/128 
... 
... 

귀하의 정보를 위해 테스트 이미지 파일도 만들었습니다. 이 같은 CImg와 함께 - 기본적으로 각 빨간색 픽셀은 x 좌표에 0.5보다 작은 작은 임의의 플롯을 더한 값으로 설정됩니다. 각 녹색 픽셀은 y 좌표에 0.5보다 작은 작은 무작위 부동 소수점을 더한 값으로 설정되고 각 파란색 픽셀은 중간 톤으로 설정됩니다.당신이 순수 libTIFF을 함께하고 싶어

#define cimg_display 0 
#define cimg_use_tiff 
#define cimg_use_png 
#include "CImg.h" 
#include <cstdlib> 

using namespace cimg_library; 

int main(){ 
    const int w=512; 
    const int h=256; 
    const int channels=3; 
    float* buffer = new float[w*h*channels]; 
    float* fp=buffer; 
    for(int y=0;y<h;y++){ 
     for(int x=0;x<w;x++){ 
     *fp++=x+float(rand())/(2.0*RAND_MAX); // red 
     } 
    } 
    for(int y=0;y<h;y++){ 
     for(int x=0;x<w;x++){ 
     *fp++=y+float(rand())/(2.0*RAND_MAX); // green 
     } 
    } 
    for(int y=0;y<h;y++){ 
     for(int x=0;x<w;x++){ 
     *fp++=128; // blue 
     } 
    } 

    CImg <float>img(buffer,w,h,1,channels); 
    img.save_tiff("result.tif"); 
} 

enter image description here

0

또 다른, 쉽게 설치할 수있는 가벼운 옵션은 vips을 사용하는 것입니다. 32 비트 TIF를 32 비트 부동 소수점의 원시 파일로 변환하여 C++ 프로그램으로 바로 읽을 수 있습니다. 명령 줄에서 파일 raw.bin에서 비 압축 포맷되지 않은 수레로 읽을

vips rawsave yourImage.tif raw.bin 

와 함께 변환을 수행. 우리가 지금 파일 raw.bin 덤프 경우, 수레로 데이터를 해석, 당신은 내 다른 답변에서와 동일한 값을 볼 수 있습니다 물론

od -f raw.bin 

0000000  3.913185e-06 2.327210e-01 1.280000e+02 1.065769e+00 
0000020  3.421732e-01 1.280000e+02 2.377803e+00 4.058807e-01 
0000040  1.280000e+02 3.229325e+00 1.371841e-01 1.280000e+02 

, 당신은 당신의 프로그램을 가질 수 libvips하거나 연결하여 변환을 system()을 사용하여 명령 행 버전을 실행 한 다음 출력 파일을 읽으십시오.

관련 문제