OpenCv+wxwidgets尝试

wxwidgets对图片的处理是按24bit来的(直接打开8bit位图不算),我需要从串口读取的数据显示图片,而受到的数据是8bit的灰度图,目前发现想把数据转成wxbitmap或wximage都要给他的每个RGB通道拷贝一份灰度数据,三个通道的合起来才是灰度图,而我找到的wxbitmap的一个构造函数确实可以从char构造bitmap,但它的位深度默认为1,即单色图,改变深度为8不能显示了直接。。。之前显示出来图片好高兴的说。。。拷贝三遍感觉好傻,我就去找别的解决办法了,我看Opencv不错,网上的例子也比较多,不像wxwidgets例子少。

基本思路是使用Mat从指向char数据区的指针创建一个Mat实例,再从Mat实现到wxbitmap转换(实际还是拷贝三遍,但这个有相应函数,比较方便),先找从char*构建Mat的方法

备选1:

 

cv::Mat::Mat(int rows,
  int cols,
  int type,
  void * data,
  size_t step = AUTO_STEP 
 )
只初始化矩阵头,不进行实际的数据拷贝
 

备选2:

 

 

Mat cv::imdecode(InputArray buf,
  int flags 
 ) 

从存储缓冲区读一副图像。

网上推荐的用法:

Mat im=imdecode(Mat(buff),CV_LOAD_IMAGE_COLOR);

buff的定义:char buff[BUFF_SIZE]={0};

应该是直接用char*构造了Mat。。

先尝试第一种:

使用线程:

 

MyThread::MyThread(aframeFrame*frame,char* rawdata,int col,int row)
        :wxThread()
{

    data=rawdata;
    width=col;
    heigth=row;
    gui=frame;
}
void *MyThread::Entry()
{
    //int linebyte=(width+3)/4*4;//存储图像的宽度要满足是4的倍数
    Mat mat(width,heigth,CV_8UC1,data);
    wxImage image;
    Mat2wxImage(mat,image);
    ToFrame(image);
    //wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED,ID_THREAD_TEST);
    //wxGetApp().AddPendingEvent(event);
    return NULL;
}
Mat MyThread::convertType(const Mat& srcImg, int toType, double alpha, double beta)
{
  Mat dstImg;
  srcImg.convertTo(dstImg, toType, alpha, beta);
  return dstImg;
}
void MyThread::Mat2wxImage(Mat &mat, wxImage  &image)
{
    // data dimension
    int w = mat.cols, h = mat.rows;//获取MAT宽度,高度
    int size = w*h*3*sizeof(unsigned char);//为WxImage分配空间数,因为其为24bit,所以*3

// allocate memory for internal wxImage data
unsigned char * wxData = (unsigned char*) malloc(size);//分配空间

// the matrix stores BGR image for conversion
Mat cvRGBImg = Mat(h, w, CV_8UC3, wxData);//转换存储用MAT

    switch (mat.channels())//根据MAT通道数进行转换
    {
    case 1: // 1-channel case: expand and copy灰度到RGB
    {
      // convert type if source is not an integer matrix
      if (mat.depth() != CV_8U)//不是unsigned char先转化
      {
        cvtColor(convertType(mat, CV_8U, 255,0), cvRGBImg, CV_GRAY2RGB);//把图片从一个颜色空间转换为另一个
      }
      else
      {
        cvtColor(mat, cvRGBImg, CV_GRAY2RGB);
      }
    } break;

    case 3: // 3-channel case: swap R&B channels
    {
      int mapping[] = {0,2,1,1,2,0}; // CV(BGR) to WX(RGB)
      // bgra[0] -> bgr[2], bgra[1] -> bgr[1], bgra[2] -> bgr[0],即转成RGB,舍弃alpha通道
      mixChannels(&mat, 1, &cvRGBImg, 1, mapping, 3);//一个输入矩阵,一个输出矩阵,maping中三个索引对
    } break;

    default://通道数量不对
    {
      wxLogError(wxT("Cv2WxImage : input image (#channel=%d) should be either 1- or 3-channel"), mat.channels());
    }
  }

  image.Destroy(); // free existing data if there's any
  image = wxImage(w, h, wxData);
}
void MyThread::ToFrame(wxImage &image)
{
    gui->Notify(image);
}

转换的程序时从网上找来的,具体参考:

点击打开链接

测试成功,图像数据如下:

 

static char buff[]={//16*20
2,	4,	6,	8,	10,	12,	14,	16,	18,	20,	22,	24,	26,	28,	30,	32,
3,	5,	7,	9,	11,	13,	15,	17,	19,	21,	23,	25,	27,	29,	31,	33,
4,	6,	8,	10,	12,	14,	16,	18,	20,	22,	24,	26,	28,	30,	32,	34,
5,	7,	9,	11,	13,	15,	17,	19,	21,	23,	25,	27,	29,	31,	33,	35,
6,	8,	10,	12,	14,	16,	18,	20,	22,	24,	26,	28,	30,	32,	34,	36,
7,	9,	11,	13,	15,	17,	19,	21,	23,	25,	27,	29,	31,	33,	35,	37,
8,	10,	12,	14,	16,	18,	20,	22,	24,	26,	28,	30,	32,	34,	36,	38,
9,	11,	13,	15,	17,	19,	21,	23,	25,	27,	29,	31,	33,	35,	37,	39,
10,	12,	14,	16,	18,	20,	22,	24,	26,	28,	30,	32,	34,	36,	38,	40,
11,	13,	15,	17,	19,	21,	23,	25,	27,	29,	31,	33,	35,	37,	39,	41,
12,	14,	16,	18,	20,	22,	24,	26,	28,	30,	32,	34,	36,	38,	40,	42,
13,	15,	17,	19,	21,	23,	25,	27,	29,	31,	33,	35,	37,	39,	41,	43,
14,	16,	18,	20,	22,	24,	26,	28,	30,	32,	34,	36,	38,	40,	42,	44,
15,	17,	19,	21,	23,	25,	27,	29,	31,	33,	35,	37,	39,	41,	43,	45,
16,	18,	20,	22,	24,	26,	28,	30,	32,	34,	36,	38,	40,	42,	44,	46,
17,	19,	21,	23,	25,	27,	29,	31,	33,	35,	37,	39,	41,	43,	45,	47,
18,	20,	22,	24,	26,	28,	30,	32,	34,	36,	38,	40,	42,	44,	46,	48,
19,	21,	23,	25,	27,	29,	31,	33,	35,	37,	39,	41,	43,	45,	47,	49,
20,	22,	24,	26,	28,	30,	32,	34,	36,	38,	40,	42,	44,	46,	48,	50,
21,	23,	25,	27,	29,	31,	33,	35,	37,	39,	41,	43,	45,	47,	49,	51,
};

图像显示如下:

 

备选2未完待续。。。。
 


 

个人研究成果,wxWidgets的外围通讯库基本一直处于空缺状态,经过几天的研究,将我个人的研究成果上传共享。 本库基于官方于2011年最后一次更新的libctb-0.16版本为基础修改而来,工程使用CodeBlocks创建,相较原版的变更如下。 1.去掉了ctb命名空间,之前用起来感觉有点别扭,所以去掉了,不过为了兼容性考虑,以后可能加回来。 2.IOBase、SerialPort(继承自IOBase)、GPIB(继承自IOBase)三个类修改了构造函数,原来FIFO缓冲的尺寸固定为256,我觉得波特率高时候可能不够用,现在改为通过构造函数传参由用户指定,示例程序中使用4096。 3.修正一个严重的BUG,在SerialPort基类中的OpenDedvice方法中,当串口附加参数为NULL时,类内的附加参数结构体成员将在没有被始化就被使用,进而因参数混乱而导致收发异常,这个BUG目前我已将其修复并进行了测试。 4.对Win32环境下的GetAvailablePorts函数进行重写,现在可以获取串口号超过20的串口(原来的最多到Com20),并且可以得到串口的设备名信息。 5.以上修改只在Windows下测试通过,我手头没有Linux环境,对Linux相关的代码基本是靠着意念盲改,如果您发现了有错误疏漏,欢迎指正,能帮我改改就更好了,比如Linux下如何取得串口设备名我就还没弄明白。 压缩包里有可以编译静态库的工程,以及一个基于wxWidgets3.1的演示工程,就是一个简单的串口收发器,供大家参考。 由于串口功能的实现需要依赖Windows系统API,在Windows下,如果使用Mingw编译,请改你连·请关联静态库libsetupapi.a与libwinmm.a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值