Pergunta

Eu preciso converter um 8-bit IplImage a um 32-bits IplImage. Usando a documentação de todo o web Eu tentei o seguinte:

// general code
img2 = cvCreateImage(cvSize(img->width, img->height), 32, 3);
int height    = img->height;
int width     = img->width;
int channels  = img->nChannels;
int step1     = img->widthStep;
int step2     = img2->widthStep;
int depth1    = img->depth;
int depth2    = img2->depth;
uchar *data1   = (uchar *)img->imageData;
uchar *data2   = (uchar *)img2->imageData;

for(h=0;h<height;h++) for(w=0;w<width;w++) for(c=0;c<channels;c++) {
   // attempt code...
}

// attempt one
// result: white image, two red spots which appear in the original image too.
// this is the closest result, what's going wrong?!
// see: http://files.dazjorz.com/cache/conversion.png
((float*)data2+h*step2+w*channels+c)[0] = data1[h*step1+w*channels+c];

// attempt two
// when I change float to unsigned long in both previous examples, I get a black screen.

// attempt three
// result: seemingly random data to the top of the screen.
data2[h*step2+w*channels*3+c] = data1[h*step1+w*channels+c];
data2[h*step2+w*channels*3+c+1] = 0x00;
data2[h*step2+w*channels*3+c+2] = 0x00;

// and then some other things. Nothing did what I wanted. I couldn't get an output
// image which looked the same as the input image.

Como você vê eu realmente não sei o que estou fazendo. Eu adoraria saber, mas eu adoraria que mais se eu pudesse conseguir este feito corretamente. Obrigado por qualquer ajuda que conseguir!

Foi útil?

Solução

Talvez este link pode ajudá-lo?

Editar Em resposta à segunda edição do OP eo comentário

Você tentou

float value = 0.5

em vez de

float value = 0x0000001;

Eu pensei que o intervalo para um valor de cor flutuador vai de 0.0 a 1.0, onde 1.0 é branco.

Outras dicas

A função que você está procurando é cvConvertScale (). Ele automagicamente faz qualquer conversão de tipo para você. Você apenas tem que especificar que você quer escala por um fator de 1/255 (que mapeia o intervalo [0 ... 255] para [0 ... 1]).

Exemplo:

IplImage *im8 = cvLoadImage(argv[1]);
IplImage *im32 = cvCreateImage(cvSize(im8->width, im8->height), 32, 3);

cvConvertScale(im8, im32, 1/255.);

Observe o ponto em 1/255. - para forçar uma divisão dupla. Sem ele você começa uma escala de 0.

flutuantes cores pontuais vão de 0.0 a 1.0, e uchars ir de 0 a 255. As seguintes correções de código-lo:

// h is height, w is width, c is current channel (0 to 2)
int b = ((uchar *)(img->imageData + h*img->widthStep))[w*img->nChannels + c];
((float *)(img2->imageData + h*img2->widthStep))[w*img2->nChannels + c] = ((float)b) / 255.0;

Muitos, muitos graças ao Stefan Schmidt por me ajudar a corrigir isso!

Se você não colocar o ponto (.), Alguns compiladores vai entender é como uma divisão int, dando-lhe um resultado int (zero neste caso).

Você pode criar um IplImage invólucro usando boost :: shared_ptr e template-metaprogramming. Eu tenho feito isso, e eu recebo a coleta de lixo automática, juntamente com conversões de imagem automáticos de uma profundidade para outro, ou de um canal para imagens multi-canal.

chamei de blImageAPI API e pode ser encontrada aqui: http://www.barbato.us/ 2010/10 / 14 / imagem-data-estrutura baseada em shared_ptr-iplimage /

É muito rápido e código make muito legível, (bom para manter algoritmos)

É também pode ser usado em vez de IplImage em algoritmos OpenCV sem mudar nada.

Boa sorte e se divertir escrevendo algoritmos !!!

IplImage * img8, * img32;
img8 = cvLoadImage ( "a.jpg", 1);

    cvNamedWindow("Convert",1);
    img32 = cvCreateImage(cvGetSize(img8),IPL_DEPTH_32F,3);
    cvConvertScale(img8,img32,1.0/255.0,0.0);

// Para Confirmação Verifique os valores de pixel (entre 0-1)

    for(int row = 0; row < img32->height; row++ ){
                float* pt = (float*) (img32->imageData + row * img32->widthStep);
                for ( int col = 0; col < width; col++ )
                            printf("\n %3.3f , %3.3f , %3.3f ",pt[3*col],pt[3*col+1],pt[3*col+2]);                  
            }

    cvShowImage("Convert",img32);
    cvWaitKey(0);
    cvReleaseImage(&img8);
    cvReleaseImage(&img32);
    cvDestroyWindow("Convert");
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top