Opencv数字图像处理颜色识别问题_opencv颜色分割

Opencv数字图像处理颜色识别问题_opencv颜色分割,第1张

1、数字图像

数字图像,又称为数码图像或数位图像,是二维图像用有限数字数值像素的表示。数字图像是由模拟图像数字化得到的、以像素为基本元素的、可以用数字计算机或数字电路存储和处理的图像。

2、数字图像处理包括内容:

图像数字化;图像变换;图像增强;图像恢复;图像压缩编码;图像分割;图像分析与描述;图像的识别分类。

3、数字图像处理系统包括部分:

输入(采集);存储;输出(显示);通信;图像处理与分析。

4、从“模拟图像”到“数字图像”要经过的步骤有:

图像信息的获取;图像信息的存储;图像信息处理;图像信息的传输;图像信息的输出和显示。

5、数字图像1600x1200什么意思?灰度一般取值范围0~255,其含义是什么?

数字图像1600x1200表示空间分辨率为1600x1200像素;灰度范围0~255指示图像的256阶灰阶,就是通过不同程度的灰色来来表示图像的明暗关系,8bit的灰度分辨率。

因为RGB2GRAY的过程中,是丢失了颜色比例信息的,丢失以后是永远也找不回来了。比如02×R(30)+05×G(100)+03×B(200)=GRAY(116),在转换过程中你最后只得到了116这个灰度值。已知的还有02 ,05, 03这个比例。还原的时候,一个方程02×R(?)+05×G(?)+03×B(?)=GRAY(116), 三个未知数,是没有唯一解的。因此无法还原成彩色图像了。

可以参考下面的程序,其中bitCount!=8 && bitCount!=24指的就是8位与24位
//BMP与IplImage相互转换
///////////////////////////////头文件bmp2iplh
//bmp2iplh
#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 ( biHeaderbiHeight ((biHeaderbiWidth biHeaderbiBitCount / 8 + 3) & (-4)));
}

public:
void Clear();
BITMAPINFOHEADER biHeader;
unsigned char bmpData;
};
#endif
/////////////////////////////////////////////////////////////////////实现文件bmp2iplcpp
#include "bmp2iplh"

/

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 图像数据大小(=heightwidthStep),单位字节
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 imageThis 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 = imgbiHeader;
PBITMAPINFOHEADER pBmpH = (PBITMAPINFOHEADER)&imgbiHeader;
memcpy(&biHeader, pBmpH, sizeof(BITMAPINFOHEADER));
biHeaderbiSizeImage = ImgSize();
bool isLowerLeft = biHeaderbiHeight>0;
//int rowSize=0;
if(!isLowerLeft) biHeaderbiHeight=-biHeaderbiHeight;

if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [biHeaderbiSizeImage];
//memcpy(bmpData, imgbmpData, imgbiHeaderbiSizeImage);
CopyData((char )bmpData, (char)imgbmpData, biHeaderbiSizeImage,
!isLowerLeft, biHeaderbiHeight);
}

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

biHeaderbiSize = sizeof(BITMAPINFOHEADER);
biHeaderbiWidth = imgwidth;
biHeaderbiHeight = imgheight;
biHeaderbiPlanes = 1;
biHeaderbiBitCount = imgdepth imgnChannels;
biHeaderbiCompression = BI_RGB;
biHeaderbiSizeImage = imgimageSize;
biHeaderbiXPelsPerMeter = 0;
biHeaderbiYPelsPerMeter = 0;
biHeaderbiClrUsed = 0;
biHeaderbiClrImportant = 0;

if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [imgimageSize];
//memcpy(bmpData, imgImageData, imgimageSize);
CopyData((char)bmpData, (char)imgimageData, imgimageSize,
isTopLeft, imgheight);
/int i,j;
CvScalar s;
for(i=0;i<imgwidth;i++)
for(j=0;j<imgheight;j++){
s=cvGet2D(&img,i,j);

}
/
}

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

biHeaderbiSize = sizeof(BITMAPINFOHEADER);
biHeaderbiWidth = width;
biHeaderbiHeight = height;
biHeaderbiPlanes = 1;
biHeaderbiBitCount = bitCount;
biHeaderbiCompression = BI_RGB;
biHeaderbiSizeImage = ImgSize();
biHeaderbiXPelsPerMeter = 0;
biHeaderbiYPelsPerMeter = 0;
biHeaderbiClrUsed = 0;
biHeaderbiClrImportant = 0;

if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [biHeaderbiSizeImage];
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; i<height; i++) {
memcpy(dest, src, rowByteSize);
dest += rowByteSize;
src -= rowByteSize;
}
}

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

IplImage iplImg;
int height;
bool isLowerLeft = biHeaderbiHeight>0;
height = (biHeaderbiHeight>0) biHeaderbiHeight : -biHeaderbiHeight;
iplImg = cvCreateImage( cvSize(biHeaderbiWidth, height), IPL_DEPTH_8U, biHeaderbiBitCount / 8);
//iplImg = cvCreateImageHeader( cvSize(biHeaderbiWidth, height), IPL_DEPTH_8U, biHeaderbiBitCount / 8);

//cvSetData(iplImg,(char)bmpData,biHeaderbiSizeImage/height);
CopyData( iplImg->imageData, (char)bmpData, biHeaderbiSizeImage,
isLowerLeft, height);
/int i,j;
CvScalar s;
int channels=biHeaderbiBitCount / 8;
int step=(biHeaderbiWidthchannels+3) & -4;
int loc=0;
for(i=0;i<iplImg->height;i++){
for(j=0;j<iplImg->width;j++){
loc=istep + jchannels;
sval[0]=bmpData[loc];
if(channels==3){
sval[1]=bmpData[loc+1];
sval[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) {
biHeaderbiWidth = newW;
biHeaderbiHeight = newH;
biHeaderbiSizeImage = ImgSize();
if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [biHeaderbiSizeImage];
Clear();
}

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

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

这个不需要见面 如果你确定是根据颜色替换的话:
对原始图和大海循环像素点。
循环遍历每一个像素点,给定一个范围(绿色的RGB范围)。
如果判断是绿色则用大海的对应位置像素点替换该像素。

如果你对背景建模了过程就更简单了。
用原始图和模版匹配,
同样进行像素点循环,匹配到的点就,用大海的像素点替换该位置上原始图的像素点

opencv中的imread函数用法为:
Mat imread(const string& filename, intflags=1 );
其中第一个参数是载入名,第二个参数是int类型的flags,为载入标识,它指定一个加载图像的颜色类型。可以看到它自带缺省值1在higui_ch中发现这个枚举的定义是这样的:
enum
{
/ 8bit, color or not /
CV_LOAD_IMAGE_UNCHANGED =-1,
/ 8bit, gray /
CV_LOAD_IMAGE_GRAYSCALE =0,
/ , color /
CV_LOAD_IMAGE_COLOR =1,
/ any depth, /
CV_LOAD_IMAGE_ANYDEPTH =2,
/ , any color /
CV_LOAD_IMAGE_ANYCOLOR =4
};
其中:
flags >0返回一个3通道的彩色图像。
flags =0返回灰度图像。
flags <0返回包含Alpha通道的加载的图像。
你用函数的时候没有设置第二个参数,就会默认值为1。尽管你读入的是灰度图,还是自动转化成三通道图像。可以将第二个参数置为0得到灰度图像


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12690032.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-27
下一篇 2023-05-27

发表评论

登录后才能评论

评论列表(0条)

保存