OpenCV和AIPCV库之间数据转换

使用OpenCV时需要了解的关键细节是图像数据结构是如何实现的。因此,要把OpenCV库和AIPCV连接起来的主要工作就在于提供一种在两种系统之间转换图像数据结构的方法。AIPCV库中的基本图像数据结构由两个数据结构组成:一个表示头信息,另一个表示图像。

struct header {

         int nr, nc;             /* Rows and columns in the image */

         int oi, oj;             /* Origin */

};

struct image {

                  struct header *info;            /* Pointer to header */

                  unsigned char **data;           /* Pixel values */

};

现在将AIPCV图像转换为OpenCV图像的方法很清晰明了,而且需要这种方法才能让图像显示在窗口中并且保存为JPEG和其他形式。IMAGE----àIplImage

IplImage *toOpenCV (IMAGE x)

{

         IplImage *img;

         unsigned char *z;

         int i=0;

        

         z = x->data[0];

//变量data[0]指向整个数组起始位置的指针,因而等同于IplImage.imageData

         img = cvCreateImage (cvSize(x->info->nc, x->info->nr), IPL_DEPTH_8U, 1);

         if (img)

           for (i=0; i<x->info->nc*x->info->nr; i++)

                  img->imageData[i] = *z++;

         return img;

}

IplImage转化为AIPCV更为复杂,因为OpenCV的图像可能是彩色的。如果是彩色的,那么如何才能转换为灰阶呢?一个彩色图像可以转换为3个单色图像(一个红色图像、一个绿色图像、一个蓝色图像),还可以构建一个使用单字节索引的色彩映射表,这个索引可以用作像素值。下面展示的解决方案将3通道彩色图像转换为灰阶图像,使用的方法是计算RGB值的平均值。IplImage----àIMAGE

IMAGE fromOpenCV (IplImage *x)

{

 

         IMAGE img;

         unsigned char *z, *y;

         int color=0, i=0;

         unsigned char k=0;

        

         if ((x->depth==IPL_DEPTH_8U) &&(x->nChannels==1))                                                                     // 1 Pixel (grey) image

                  img = newimage (x->height, x->width);

         else if ((x->depth==8) && (x->nChannels==3)) //Color

         {

                  color = 1;

                  img = newimage (x->height, x->width);

         }

         else return 0;

 

         z = (unsigned char *)(x->imageData);

         y = img->data[0];

 

         for (i=0; i<x->height*x->width; i++)

         {

                  if (color) k = ((*z++) + (*z++) + (*z++))/3;

                  else k = *z++;

                  *(y++) = k;

         }

         return img;

}

 

例子:用Otsu设计的灰阶直方图方法进行阈值分割,

// thresh.c : Threshold an image. Use OpenCV AND AIPCV

//#include "stdafx.h"

#include <stdlib.h>

#include <stdio.h>

#include <math.h>

#include <cv.h>

#include <highgui.h>

 

#include <malloc.h>

#include <fcntl.h>

#include <io.h>

 

/* The image header data structure      */

struct header {

         int nr, nc;             /* Rows and columns in the image */

         int oi, oj;             /* Origin */

};

 

/*      The IMAGE data structure        */

struct image {

                  struct header *info;            /* Pointer to header */

                  unsigned char **data;           /* Pixel values */

};

typedef struct image * IMAGE;

 

IMAGE newimage (int nr, int nc)

{

         struct image  *x;                /* New image */

         int i;

 

         if (nr < 0 || nc < 0) {

                  printf ("Error: Bad image size (%d,%d)\n", nr, nc);

                  return 0;

         }

 

/*      Allocate the image structure    */

         x = (struct image  *) malloc( sizeof (struct image) );

         if (!x)

         {

                  printf ("Out of storage in NEWIMAGE.\n");

                  return 0;

         }

 

/*      Allocate and initialize the header      */

 

         x->info = (struct header *)malloc( sizeof(struct header) );

         if (!(x->info))

         {

                  printf ("Out of storage in NEWIMAGE.\n");

                  return 0;

         }

         x->info->nr = nr;       x->info->nc = nc;

         x->info->oi = x->info->oj = 0;

 

/*      Allocate the pixel array        */

 

         x->data = (unsigned char **)malloc(sizeof(unsigned char *)*nr);

 

/* Pointers to rows */

         if (!(x->data))

         {

                  printf ("Out of storage in NEWIMAGE.\n");

                  return 0;

         }

 

         x->data[0] = (unsigned char *)malloc (nr*nc);

         if (x->data[0]==0)

           {

                  printf ("Out of storage. Newimage.\n");

                  exit(1);

           }

 

         for (i=1; i<nr; i++)

         {

           x->data[i] = (x->data[0]+nr*i);

         }

 

         return x;

}

 

void freeimage (struct image  *z)

{

/*      Free the storage associated with the image Z    */

 

         if (z != 0)

         {

            free (z->info);

            free (z->data);

            free (z);

         }

}

 

/* Otsu's method of 'grey level histograms' */

float nu (float *p, int k, float ut, float vt);

float u (float *p, int k);

void thr_glh (IMAGE im);

 

 

void thr_glh (IMAGE x)

{

/*     Threshold selection using grey level histograms. SMC-9 No 1 Jan 1979

                  N. Otsu                                                        */

 

         int i,j,k,n,m, h[260], t;

         float y, z, p[260];

         unsigned char *pp;

         float ut, vt;

 

         n = x->info->nr*x->info->nc;

         for (i=0; i<260; i++) {                /* Zero the histograms  */

                  h[i] = 0;

                  p[i] = 0.0;

         }

 

                          /* 累计直方图 */

         for (i=0; i<x->info->nr; i++)

            for (j=0; j<x->info->nc; j++) {

                     k = x->data[i][j];

                  h[k+1] += 1;

            }

 

         for (i=1; i<=256; i++)                /*均一化 */

                  p[i] = (float)h[i]/(float)n;

 

         ut = u(p, 256);          /* Global mean */

         vt = 0.0;            /* Global Variance */

         for (i=1; i<=256; i++)

                  vt += (i-ut)*(i-ut)*p[i];

 

         j = -1; k = -1;

         for (i=1; i<=256; i++) {

                  if ((j<0) && (p[i] > 0.0)) j = i;   /* First index */

                  if (p[i] > 0.0) k = i;                     /* Last index  */

         }

         z = -1.0;

         m = -1;

         for (i=j; i<=k; i++) {

                  y = nu (p, i, ut, vt);           /* Compute NU */

                  if (y>=z) {                  /* Is it the biggest? */

                          z = y;                          /* Yes. Save value and i */

                          m = i;

                  }

         }

 

         t = m;

         printf("Threshold found is %d\n", t);

 

/* Threshold */

         pp = x->data[0];

         for (i=0; i<n; i++)

           if (*pp < t)

             *pp++ = 0;

           else

             *pp++ = 255;

}

 

float w (float *p, int k)

{

         int i;

         float x=0.0;

 

         for (i=1; i<=k; i++) x += p[i];

         return x;

}

 

float u (float *p, int k)

{

         int i;

         float x=0.0;

 

         for (i=1; i<=k; i++) x += (float)i*p[i];

         return x;

}

 

float nu (float *p, int k, float ut, float vt)

{

         float x, y;

 

         y = w(p,k);

         x = ut*y - u(p,k);

         x = x*x;

         y = y*(1.0F-y);

         if (y>0) x = x/y;

          else x = 0.0;

         return x/vt;

}

 

IplImage *toOpenCV (IMAGE x)

{

         IplImage *img;

         unsigned char *z;

         int i=0;

        

         z = x->data[0];

         img = cvCreateImage (cvSize(x->info->nc, x->info->nr), IPL_DEPTH_8U, 1);

         if (img)

           for (i=0; i<x->info->nc*x->info->nr; i++)

                  img->imageData[i] = *z++;

         return img;

}

 

IMAGE fromOpenCV (IplImage *x)

{

 

         IMAGE img;

         unsigned char *z, *y;

         int color=0, i=0;

         unsigned char k=0;

        

         if ((x->depth==IPL_DEPTH_8U) &&(x->nChannels==1))                                                                     // 1 Pixel (grey) image

                  img = newimage (x->height, x->width);

         else if ((x->depth==8) && (x->nChannels==3)) //Color

         {

                  color = 1;

                  img = newimage (x->height, x->width);

         }

         else return 0;

         z = (unsigned char *)(x->imageData);

         y = img->data[0];

         for (i=0; i<x->height*x->width; i++)

         {

                  if (color) k = ((*z++) + (*z++) + (*z++))/3;

                  else k = *z++;

                  *(y++) = k;

         }

         return img;

}

 

int main(int argc, char *argv[])

{

  IplImage* img=0;

  IplImage* img2=0;

  IMAGE x;

  int height,width,step,channels;

  uchar *data;

  int mean=0,count=0;

 

  if(argc<1){

    printf("Usage: main <image-file-name>\n\7");

    exit(0);

  }

  // load an image 

  img=cvLoadImage("E:/image/Lina.bmp");

  if(!img){

    printf("Could not load image file: %s\n",argv[1]);

    exit(0);

  }

  // get the image data

  height    = img->height;

  width     = img->width;

  step      = img->widthStep;

  channels  = img->nChannels;

  data      = (uchar *)img->imageData;

  printf("Processing a %dx%d image with %d channels\n",height,width,channels);

  // create a window

  cvNamedWindow("win1", CV_WINDOW_AUTOSIZE);

  cvMoveWindow("win1", 100, 100);

 

  // show the image

  cvShowImage("win1", img );

 

  // Convert to AIPCV IMAGE type

  x = fromOpenCV (img);

  if (x)

  {

           thr_glh (x);

           img2 = toOpenCV (x);

           cvNamedWindow( "thresh");

           cvShowImage( "thresh", img2 );

           cvSaveImage( "thresholded.jpg", img2 );

  }

   // wait for a key

  cvWaitKey(0);

 

  // release the image

  cvReleaseImage(&img );

  return 0;

}

结果如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值