本文以常見的二維BMP圖像爲例,對比OpenCV, QT, ITK庫對圖像像素級的操作。
(1)OpenCV由IplImage對圖像像素級的操作, 要考慮RGB分量;
IplImage* img = cvLoadImage("D:/openCV/Project/readImage/data/binary.bmp");
uchar temp = image->imageData[y * image->widthStep + x];//widthStep = width * 3, 對應RGB3個分量
(2)QT由QImage對圖像像素級的操作,要考慮ARGB分量;
QImage* img = new QImage();
img->load("D:/openCV/Project/readImage/data/binary.bmp");
unsigned char* data = img->bits();//獲取圖像像素字節數據的首地址
(3)ITK由reader指針對圖像像素級的操作,不要考慮RGB分量;
typedef itk::ImageFileReader< InputImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
具體代碼實現:
(1)OpenCV由IplImage對BMP圖像灰度值反轉
IplImage* invertIntensity(IplImage* image)
{
for(int y = 0; y < image->height; y++)
for(int x = 0; x < image->widthStep; x++)
{
//widthStep = width * 3, 對應RGB3個分量
uchar temp = image->imageData[y * image->widthStep + x];
if(temp == 0)
image->imageData[y * image->widthStep + x] = 255;
else
image->imageData[y * image->widthStep + x] = 0;
}
return image;
}
(2)QT由QImage對BMP圖像灰度值反轉
//qimage爲自定義類名
void qimage:: invertIntensity()
{
QImage* img = new QImage();
QImage* outImg;
img->load("D:/openCV/Project/readImage/data/binary.bmp");
QGraphicsScene* sceneImg = new QGraphicsScene();
sceneImg->addPixmap(QPixmap::fromImage(*img));
ui->originalImg->setScene(sceneImg);
ui->originalImg->show();
//invert intensity
unsigned char* data = img->bits();//獲取圖像像素字節數據的首地址
int height = img->height();
int width = img->width();
int bytesPerLine = img->bytesPerLine();//width * 4, 與OpenCV中區分
unsigned char* outdata = new unsigned char[bytesPerLine * height];
for(int y = 0; y < height; y++)
for(int x = 0; x < width; x++)
{
if(data[y * bytesPerLine + x * 4] == 0)
{
outdata[y * bytesPerLine + x * 4 ] = 255;//B
outdata[y * bytesPerLine + x * 4 + 1] = 255;//G
outdata[y * bytesPerLine + x * 4 + 2] = 255;//R
//A, 該分量保持不變
outdata[y * bytesPerLine + x * 4 + 3] = data[y * bytesPerLine + x * 4 + 3];
}
else
{
outdata[y * bytesPerLine + x * 4 ] = 0;
outdata[y * bytesPerLine + x * 4 + 1] = 0;
outdata[y * bytesPerLine + x * 4 + 2] = 0;
outdata[y * bytesPerLine + x * 4 + 3] = data[y * bytesPerLine + x * 4 + 3];
}
}
//QImage::Format_RGB32, 有多種格式,選擇合適的格式很重要
outImg = new QImage(outdata,width,height,bytesPerLine,QImage::Format_RGB32);
//初始圖,結果圖要對應不同的 QGraphicsScene*
QGraphicsScene* sceneOutImg = new QGraphicsScene();
sceneOutImg->addPixmap(QPixmap::fromImage(*outImg));
ui->resultImg->setScene(sceneOutImg);
ui->resultImg->show();
delete[]outImg;
}
(3)ITK由reader指針對BMP圖像灰度值反轉
reader->SetFileName( argv[1] );
reader->Update();
inputImage = reader->GetOutput();
//獲取圖像尺寸
InputImageType::SizeType imgSize = inputImage->GetLargestPossibleRegion().GetSize();
//直接訪問bmp圖像內存, 不考慮RGB三個分量
InputImageType::IndexType index;
for(int y = 0; y < imgSize[1]; y++)
for(int x = 0; x < imgSize[0]; x++)
{
index[0] = x;
index[1] = y;
unsigned char temp;
temp = inputImage->GetPixel(index);
if(temp == 0)
inputImage->SetPixel(index, 255);
else
inputImage->SetPixel(index, 0);
}
讀入BMP圖像,經過灰度值反轉後,結果基於QT顯示,左圖爲原圖,右圖爲結果圖: