一、图像格式间相互转换
1.BYTE转QImage、HObject和Mat
Balser下相机图像数据转换成QImage、Mat、HObject
QImage Qimg;
Mat cvImg;
HObject hvImg;
//格式转换
m_formatConverter.Convert(pylonImage, ptrGrabResult);
uchar * din = (uchar *)(pylonImage.GetBuffer()); //数据指针
//单通道Momo
if(IsMono(pylonImage.GetPixelType()))
{
qDebug()<<"黑白图像";
Qimg = QImage(din, ptrGrabResult->GetWidth(), ptrGrabResult->GetHeight(), QImage::Format_Indexed8);
cvImg = Mat(ptrGrabResult->GetHeight(),ptrGrabResult->GetWidth(),CV_8UC1,din).clone();
GenImage1Extern(&hvImg,"byte",(HTuple)ptrGrabResult->GetWidth(),(HTuple)ptrGrabResult->GetHeight(),(long)din,NULL); //Mono
}
else
{
//此处可以根据相机的格式获取特定格式的彩色图像
if(IsRGB(pylonImage.GetPixelType()))
{
Qimg = QImage(din, ptrGrabResult->GetWidth(), ptrGrabResult->GetHeight(), QImage::Format_RGB888);
cvImg = Mat(ptrGrabResult->GetHeight(),ptrGrabResult->GetWidth(),CV_8UC3,din).clone();
GenImageInterleaved (&hvImg,(long)din, "rgb", (HTuple)ptrGrabResult->GetWidth(),(HTuple)ptrGrabResult->GetHeight(), 0, "byte", 0, 0, 0, 0, 8, 0);
}
}
2.QImage、HObject和Mat的相互转换
QImage转HObject
HObject Widget::QImage2HObject(QImage qimage)
{
HObject hv_image;
int width = qimage.width();
int height = qimage.height();
QImage::Format format = qimage.format();
if(format == QImage::Format_RGB32 ||
format == QImage::Format_ARGB32 ||
format == QImage::Format_ARGB32_Premultiplied)
{
GenImageInterleaved(&hv_image,(Hlong)qimage.bits(),"bgrx",qimage.width(),qimage.height(),0,"byte",width, height, 0, 0, 8, 0);
}
else if(format == QImage::Format_RGB888)
{
GenImageInterleaved(&hv_image,(Hlong)qimage.bits(),"bgr",qimage.width(),qimage.height(),0,"byte",width, height, 0, 0, 8, 0);
}
else if(format == QImage::Format_Grayscale8 || format == QImage::Format_Indexed8)
{
GenImage1(&hv_image,"byte", width, height, (Hlong)qimage.bits());
}
return hv_image;
}
HObject转QImage
void HObjectToQImage(HObject hv_image, QImage &qimage)
{
HTuple hChannels,htype,hpointer;
HTuple width=0;
HTuple height=0;
ConvertImageType(hv_image,&hv_image,"byte");//将图片转化成byte类型
CountChannels(hv_image,&hChannels); //判断图像通道数
if(hChannels[0].I()==1)//单通道图
{
unsigned char *ptr;
GetImagePointer1(hv_image,&hpointer,&htype,&width,&height);
ptr=(unsigned char *)hpointer[0].L();
qimage= QImage(ptr,width,height,QImage::Format_Indexed8);
}
else if(hChannels[0].I()==3)//三通道图
{
unsigned char *ptr3;
HObject ho_ImageInterleaved;
rgb3_to_interleaved(hv_image, &ho_ImageInterleaved);
GetImagePointer1(ho_ImageInterleaved, &hpointer, &htype, &width, &height);
ptr3=(unsigned char *)hpointer[0].L();
qimage= QImage(ptr3,width/3,height,width,QImage::Format_RGB888);
}
}
void rgb3_to_interleaved (HObject ho_ImageRGB, HObject *ho_ImageInterleaved)
{
// Local iconic variables
HObject ho_ImageAffineTrans, ho_ImageRed, ho_ImageGreen;
HObject ho_ImageBlue, ho_RegionGrid, ho_RegionMoved, ho_RegionClipped;
// Local control variables
HTuple hv_PointerRed, hv_PointerGreen, hv_PointerBlue;
HTuple hv_Type, hv_Width, hv_Height, hv_HomMat2DIdentity;
HTuple hv_HomMat2DScale;
GetImagePointer3(ho_ImageRGB, &hv_PointerRed, &hv_PointerGreen, &hv_PointerBlue,
&hv_Type, &hv_Width, &hv_Height);
GenImageConst(&(*ho_ImageInterleaved), "byte", hv_Width*3, hv_Height);
//
HomMat2dIdentity(&hv_HomMat2DIdentity);
HomMat2dScale(hv_HomMat2DIdentity, 1, 3, 0, 0, &hv_HomMat2DScale);
AffineTransImageSize(ho_ImageRGB, &ho_ImageAffineTrans, hv_HomMat2DScale, "constant",
hv_Width*3, hv_Height);
//
Decompose3(ho_ImageAffineTrans, &ho_ImageRed, &ho_ImageGreen, &ho_ImageBlue);
GenGridRegion(&ho_RegionGrid, 2*hv_Height, 3, "lines", hv_Width*3, hv_Height+1);
MoveRegion(ho_RegionGrid, &ho_RegionMoved, -1, 0);
ClipRegion(ho_RegionMoved, &ho_RegionClipped, 0, 0, hv_Height-1, (3*hv_Width)-1);
ReduceDomain(ho_ImageRed, ho_RegionClipped, &ho_ImageRed);
MoveRegion(ho_RegionGrid, &ho_RegionMoved, -1, 1);
ClipRegion(ho_RegionMoved, &ho_RegionClipped, 0, 0, hv_Height-1, (3*hv_Width)-1);
ReduceDomain(ho_ImageGreen, ho_RegionClipped, &ho_ImageGreen);
MoveRegion(ho_RegionGrid, &ho_RegionMoved, -1, 2);
ClipRegion(ho_RegionMoved, &ho_RegionClipped, 0, 0, hv_Height-1, (3*hv_Width)-1);
ReduceDomain(ho_ImageBlue, ho_RegionClipped, &ho_ImageBlue);
OverpaintGray((*ho_ImageInterleaved), ho_ImageRed);
OverpaintGray((*ho_ImageInterleaved), ho_ImageGreen);
OverpaintGray((*ho_ImageInterleaved), ho_ImageBlue);
return;
}
HObject和Mat互转
using namespace cv;
using namespace Halcon;
//HObject转Mat
Mat HObject2Mat(HObject Hobj)
{
HTuple htCh = HTuple();
HString cType;
cv::Mat Image;
ConvertImageType(Hobj,&Hobj,"byte");
CountChannels(Hobj,&htch);
Hlong wid = 0;
Hlong hgt = 0;
if(htch[0].I() == 1)
{
HImage hImg(Hobj);
void *ptr = hImg.GetImagePointer1(&cType,&wid,&hgt);
int W = wid;
int H = hgt;
Image.create(H,W,CV_8UC1);
unsigned char *pdata = static_case(ptr);
memcpy(Image.data,pdata,W*H);
}
else if (htch[0].I() == 3)
{
void *Rptr;
void *Gptr;
void *Bptr;
HImage hImg(Hobj);
hImg.GetImagePointer3(&Rptr,&Gptr,&Bptr,&cType,&wid,&hgt);
int W = wid;
int H = hgt;
Image.create(H,W,CV_8UC3);
vector VecM(3);
VecM[0].create(H,W,CV_8UC1);
VecM[1].create(H,W,CV_8UC1);
VecM[2].create(H,W,CV_8UC1);
unsigned char *R = (unsigned char *)Rptr;
unsigned char *G = (unsigned char *)Gptr;
unsigned char *B = (unsigned char *)Bptr;
memcpy(VecM[2].data,R,W*H);
memcpy(VecM[1].data,G,W*H);
memcpy(VecM[0].data,B,W*H);
cv::merge(VecM,Image);
}
return Image;
}
//Mat转Hobject
Hobject Mat2Hobject(Mat& image)
{
Hobject Hobj = Hobject();
int hgt = image.rows;
int wid = image.cols;
int i;
if (image.type() == CV_8UC3)
{
vector imgchannel;
split(image, imgchannel);
Mat imgB = imgchannel[0];
Mat imgG = imgchannel[1];
Mat imgR = imgchannel[2];
uchar* dataR = new uchar[hgt*wid];
uchar* dataG = new uchar[hgt*wid];
uchar* dataB = new uchar[hgt*wid];
for (i = 0; i < hgt; i++)
{
memcpy(dataR + wid*i, imgR.data + imgR.step*i, wid);
memcpy(dataG + wid*i, imgG.data + imgG.step*i, wid);
memcpy(dataB + wid*i, imgB.data + imgB.step*i, wid);
}
gen_image3(&Hobj, "byte", wid, hgt, (Hlong)dataR, (Hlong)dataG, (Hlong)dataB);
delete[]dataR;
delete[]dataG;
delete[]dataB;
dataR = NULL;
dataG = NULL;
dataB = NULL;
}
else if (image.type() == CV_8UC1)
{
uchar* data = new uchar[hgt*wid];
for (i = 0; i < hgt; i++)
memcpy(data + wid*i, image.data + image.step*i, wid);
gen_image1(&Hobj, "byte", wid, hgt, (Hlong)data);
delete[] data;
data = NULL;
}
return Hobj;
}
Mat转QImage
QImage cvMat2QImage(const cv::Mat &mat)
{
switch ( mat.type() )
{
// 8-bit 4 channel
case CV_8UC4:
{
QImage image( (const uchar*)mat.data, mat.cols, mat.rows, static_cast(mat.step), QImage::Format_RGB32 );
return image;
}
// 8-bit 3 channel
case CV_8UC3:
{
QImage image( (const uchar*)mat.data, mat.cols, mat.rows, static_cast(mat.step), QImage::Format_RGB888 );
return image.rgbSwapped();
}
// 8-bit 1 channel
case CV_8UC1:
{
static QVector sColorTable;
// only create our color table once
if ( sColorTable.isEmpty() )
{
sColorTable.resize( 256 );
for ( int i = 0; i < 256; ++i )
{
sColorTable[i] = qRgb( i, i, i );
}
}
QImage image( (const uchar*)mat.data, mat.cols, mat.rows, static_cast(mat.step), QImage::Format_Indexed8 );
image.setColorTable( sColorTable );
return image;
}
default:
qDebug("Image format is not supported: depth=%d and %d channels\n", mat.depth(), mat.channels());
qWarning() << "cvMatToQImage - cv::Mat image type not handled in switch:" << mat.type();
break;
}
return QImage();
}
QImage转Mat
Mat QImage2Mat(QImage image)
{
Mat cvMat;
qDebug()<
二、图像显示方法
目前图像显示使用三种方法,第一种是QImage显示在Qlabel上,第二种方法是使用QGraphicsView来显示QImage,第三种方法是将Halcon的窗口贴在QLabel上,在Halcon的窗口上显示图像。
1.QLabel显示QPixmap图像
qDebug()<<"显示图像";
QPixmap m_pix = QPixmap::fromImage(img);
m_pix = m_pix.scaled(ui->lbl_PicShow->size(), Qt::KeepAspectRatio);
ui->lbl_PicShow->setPixmap(m_pix);
2.QGraphicsView显示QPixmap
首先用QGraphics View控件,创建QGraphicsScene背景和QGraphicsPixmapItem组件
m_scene = new QGraphicsScene();
ImageItem = new QGraphicsPixmapItem();
ImageItem->setFlag(QGraphicsItem::ItemIsMovable,false);
m_scene->addItem(ImageItem);
ui->PicShow->setScene(m_scene);
QPixmap m_pix = QPixmap::fromImage(Qimg);
m_pix = m_pix.scaled(ui->PicShow->size(), Qt::KeepAspectRatio);
ImageItem->setPixmap(m_pix);
3.Halcon窗口显示HObject图像
首先要在控件上创建Halcon窗口句柄
OpenWindow(0,0,ui->PicShow->width(),ui->PicShow->height(),m_hLabelID,"visible","",&m_hHalconID);
GetImageSize(CurTestImg,&hv_Width,&hv_Height);
SetPart(m_hHalconID, 0, 0, hv_Height-1, hv_Width-1);
dispOnWindow(CurTestImg,m_hHalconID);
总结
目前图像格式主要是QImage,主要用于Qt的显示和图像操作,HObject是Halcon的格式,图像处理要使用Halcon算法库的,要将图像转成HObject后进行图像处理运算,Mat是OpenCV的图像格式,调用OpenCV的图像算法库,要转换成对应的Mat格式。显示方法上第二种具有图层的概念,可以针对需要对显示的图像和文字进行拖动隐藏等操作。