在MFC下自己构造一个DIB类实现上述功能还是有很多现成的代码~
下面就是一个构造的DIB类,但是仅仅提供了最基本的一些 *** 作,代码来自《Visual C++数字图像处理典型算法及实现》。// DibImageh: interface for the CDibImage class
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_)
#define AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
DECLARE_HANDLE(HDIB); // DIB句柄
#define PALVERSION 0x300 // DIB常量
/ DIB宏 /
// 判断是否是Win 30的DIB
#define IS_WIN30_DIB(lpbi) (((LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
// 计算矩形区域的宽度
#define RECTWIDTH(lpRect) ((lpRect)->right - (lpRect)->left)
// 计算矩形区域的高度
#define RECTHEIGHT(lpRect) ((lpRect)->bottom - (lpRect)->top)
// 在计算图像大小时,采用公式:biSizeImage = biWidth' × biHeight。
// 是biWidth',而不是biWidth,这里的biWidth'必须是4的整倍数,表示
// 大于或等于biWidth的,离4最近的整倍数。WIDTHBYTES就是用来计算
// biWidth'
#define WIDTHBYTES(bits) (((bits) + 31) / 32 4)
// Dib文件头标志(字符串"BM",写DIB时用到该常数)
#define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
class CDibImage
{
// Constructor and Destructor ///////////////////////////////
public:
CDibImage();
virtual ~CDibImage();
// function /////////////////////////////////////////////////
public:
BOOL PaintDIB (HDC, LPRECT, HDIB, LPRECT, CPalette pPal);
BOOL CreateDIBPalette(HDIB hDIB, CPalette cPal);
LPSTR FindDIBBits (LPSTR lpbi);
DWORD DIBWidth (LPSTR lpDIB);
DWORD DIBHeight (LPSTR lpDIB);
WORD PaletteSize (LPSTR lpbi);
WORD DIBNumColors (LPSTR lpbi);
HGLOBAL CopyHandle (HGLOBAL h);
BOOL SaveDIB (HDIB hDib, CFile& file);
HDIB ReadDIBFile(CFile& file);
};
#endif // !defined(AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_)
///////////////////////////////////////////////////////////////////////
// DibImagecpp: implementation of the CDibImage class
// DIB(Independent Bitmap) 函数:
//
// PaintDIB() - 绘制DIB对象
// CreateDIBPalette() - 创建DIB对象调色板
// FindDIBBits() - 返回DIB图像象素起始位置
// DIBWidth() - 返回DIB宽度
// DIBHeight() - 返回DIB高度
// PaletteSize() - 返回DIB调色板大小
// DIBNumColors() - 计算DIB调色板颜色数目
// CopyHandle() - 拷贝内存块
//
// SaveDIB() - 将DIB保存到指定文件中
// ReadDIBFile() - 重指定文件中读取DIB对象
//////////////////////////////////////////////////////////////////////
#include "stdafxh"
#include "DIBDisplayh"
#include "DibImageh"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDibImage::CDibImage()
{
}
CDibImage::~CDibImage()
{
}
//////////////////////////////////////////////////////////////////////
// function
//////////////////////////////////////////////////////////////////////
/
函数名称:
PaintDIB()
参数:
HDC hDC - 输出设备DC
LPRECT lpDCRect - 绘制矩形区域
HDIB hDIB - 指向DIB对象的指针
LPRECT lpDIBRect - 要输出的DIB区域
CPalette pPal - 指向DIB对象调色板的指针
返回值:
BOOL - 绘制成功返回TRUE,否则返回FALSE。
说明:
该函数主要用来绘制DIB对象。其中调用了StretchDIBits()或者
SetDIBitsToDevice()来绘制DIB对象。输出的设备由由参数hDC指
定;绘制的矩形区域由参数lpDCRect指定;输出DIB的区域由参数
lpDIBRect指定。
/
BOOL CDibImage::PaintDIB(HDC hDC,
LPRECT lpDCRect,
HDIB hDIB,
LPRECT lpDIBRect,
CPalette pPal)
{
LPSTR lpDIBHdr; // BITMAPINFOHEADER指针
LPSTR lpDIBBits; // DIB象素指针
BOOL bSuccess=FALSE; // 成功标志
HPALETTE hPal=NULL; // DIB调色板
HPALETTE hOldPal=NULL; // 以前的调色板
if (hDIB == NULL)
{
return FALSE;
}
lpDIBHdr = (LPSTR)::GlobalLock((HGLOBAL) hDIB);// 锁定DIB
lpDIBBits = FindDIBBits(lpDIBHdr); // 找到DIB图像象素起始位置
if (pPal != NULL) // 获取DIB调色板,并选中它
{
hPal = (HPALETTE) pPal->m_hObject;
hOldPal = ::SelectPalette(hDC, hPal, TRUE); // 选中调色板
}
::SetStretchBltMode(hDC, COLORONCOLOR); // 设置显示模式
// 判断是调用StretchDIBits()还是SetDIBitsToDevice()来绘制DIB对象
if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
{
// 原始大小,不用拉伸。
bSuccess = ::SetDIBitsToDevice(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
(int)DIBHeight(lpDIBHdr) -
lpDIBRect->top -
RECTHEIGHT(lpDIBRect), // SrcY
0, // nStartScan
(WORD)DIBHeight(lpDIBHdr), // nNumScans
lpDIBBits, // lpBits
(LPBITMAPINFO)lpDIBHdr, // lpBitsInfo
DIB_RGB_COLORS); // wUsage
}
else
{
// 非原始大小,拉伸。
bSuccess = ::StretchDIBits(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
lpDIBRect->top, // SrcY
RECTWIDTH(lpDIBRect), // wSrcWidth
RECTHEIGHT(lpDIBRect), // wSrcHeight
lpDIBBits, // lpBits
(LPBITMAPINFO)lpDIBHdr, // lpBitsInfo
DIB_RGB_COLORS, // wUsage
SRCCOPY); // dwROP
}
::GlobalUnlock((HGLOBAL) hDIB); // 解除锁定
if (hOldPal != NULL)
{
::SelectPalette(hDC, hOldPal, TRUE); // 恢复以前的调色板
}
return bSuccess;
}
/
函数名称:
CreateDIBPalette()
参数:
HDIB hDIB - 指向DIB对象的指针
CPalette pPal - 指向DIB对象调色板的指针
返回值:
BOOL - 创建成功返回TRUE,否则返回FALSE。
说明:
该函数按照DIB创建一个逻辑调色板,从DIB中读取颜色表并存到调色板中,
最后按照该逻辑调色板创建一个新的调色板,并返回该调色板的句柄。这样
可以用最好的颜色来显示DIB图像。
/
BOOL CDibImage::CreateDIBPalette(HDIB hDIB, CPalette pPal)
{
LPLOGPALETTE lpPal; // 指向逻辑调色板的指针
HANDLE hLogPal; // 逻辑调色板的句柄
HPALETTE hPal = NULL; // 调色板的句柄
int i; // 循环变量
WORD wNumColors; // 颜色表中的颜色数目
LPSTR lpbi; // 指向DIB的指针
LPBITMAPINFO lpbmi; // 指向BITMAPINFO结构的指针(Win30)
LPBITMAPCOREINFO lpbmc; // 指向BITMAPCOREINFO结构的指针
BOOL bWinStyleDIB; // 表明是否是Win30 DIB的标记
BOOL bResult = FALSE; // 创建结果
if (hDIB == NULL)
{
return FALSE;
}
lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); // 锁定DIB
lpbmi = (LPBITMAPINFO)lpbi; // 获取指向BITMAPINFO结构的指针(Win30)
lpbmc = (LPBITMAPCOREINFO)lpbi; // 获取指向BITMAPCOREINFO结构的指针
wNumColors = DIBNumColors(lpbi);// 获取DIB中颜色表中的颜色数目
if (wNumColors != 0)
{
// 分配为逻辑调色板内存
hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
+ sizeof(PALETTEENTRY)
wNumColors);
// 如果内存不足,退出
if (hLogPal == 0)
{
::GlobalUnlock((HGLOBAL) hDIB); // 解除锁定
return FALSE;
}
lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);
lpPal->palVersion = PALVERSION; // 设置版本号
lpPal->palNumEntries = (WORD)wNumColors;// 设置颜色数目
bWinStyleDIB = IS_WIN30_DIB(lpbi); // 判断是否是WIN30的DIB
// 读取调色板
for (i = 0; i < (int)wNumColors; i++)
{
if (bWinStyleDIB)
{
// 读取红色绿色蓝色分量
lpPal->palPalEntry[i]peRed = lpbmi->bmiColors[i]rgbRed;
lpPal->palPalEntry[i]peGreen = lpbmi->bmiColors[i]rgbGreen;
lpPal->palPalEntry[i]peBlue = lpbmi->bmiColors[i]rgbBlue;
// 保留位
lpPal->palPalEntry[i]peFlags = 0;
}
else
{
// 读取红色绿色蓝色分量
lpPal->palPalEntry[i]peRed = lpbmc->bmciColors[i]rgbtRed;
lpPal->palPalEntry[i]peGreen = lpbmc->bmciColors[i]rgbtGreen;
lpPal->palPalEntry[i]peBlue = lpbmc->bmciColors[i]rgbtBlue;
// 保留位
lpPal->palPalEntry[i]peFlags = 0;
}
}
bResult = pPal->CreatePalette(lpPal);// 按照逻辑调色板创建调色板,并返回指针
::GlobalUnlock((HGLOBAL) hLogPal); // 解除锁定
::GlobalFree((HGLOBAL) hLogPal); // 释放逻辑调色板
}
::GlobalUnlock((HGLOBAL) hDIB); // 解除锁定
return bResult;
}
/
函数名称:
FindDIBBits()
参数:
LPSTR lpbi - 指向DIB对象的指针
返回值:
LPSTR - 指向DIB图像象素起始位置
说明:
该函数计算DIB中图像象素的起始位置,并返回指向它的指针。
/
LPSTR CDibImage::FindDIBBits(LPSTR lpbi)
{
return (lpbi + (LPDWORD)lpbi + PaletteSize(lpbi));
}
/
函数名称:
DIBWidth()
参数:
LPSTR lpbi - 指向DIB对象的指针
返回值:
DWORD - DIB中图像的宽度
说明:
该函数返回DIB中图像的宽度。对于Windows 30 DIB,返回BITMAPINFOHEADER
中的biWidth值;对于其它返回BITMAPCOREHEADER中的bcWidth值。
/
DWORD CDibImage::DIBWidth(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi; // 指向BITMAPINFO结构的指针(Win30)
LPBITMAPCOREHEADER lpbmc; // 指向BITMAPCOREINFO结构的指针
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
// 返回DIB中图像的宽度
if (IS_WIN30_DIB(lpDIB))
{
return lpbmi->biWidth; // 对于Windows 30 DIB,返回lpbmi->biWidth
}
else
{
return (DWORD)lpbmc->bcWidth; // 对于其它格式的DIB,返回lpbmc->bcWidth
}
}
/
函数名称:
DIBHeight()
参数:
LPSTR lpDIB - 指向DIB对象的指针
返回值:
DWORD - DIB中图像的高度
说明:
该函数返回DIB中图像的高度。对于Windows 30 DIB,返回BITMAPINFOHEADER
中的biHeight值;对于其它返回BITMAPCOREHEADER中的bcHeight值。
/
DWORD CDibImage::DIBHeight(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi; // 指向BITMAPINFO结构的指针(Win30)
LPBITMAPCOREHEADER lpbmc; // 指向BITMAPCOREINFO结构的指针
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
// 返回DIB中图像的宽度
if (IS_WIN30_DIB(lpDIB))
{
return lpbmi->biHeight; // 对于Windows 30 DIB,返回lpbmi->biHeight
}
else
{
return (DWORD)lpbmc->bcHeight; // 对于其它格式的DIB,返回lpbmc->bcHeight
}
}
/
函数名称:
PaletteSize()
参数:
LPSTR lpbi - 指向DIB对象的指针
返回值:
WORD - DIB中调色板的大小
说明:
该函数返回DIB中调色板的大小。对于Windows 30 DIB,返回颜色数目×
RGBQUAD的大小;对于其它返回颜色数目×RGBTRIPLE的大小。
/
WORD CDibImage::PaletteSize(LPSTR lpbi)
{
// 计算DIB中调色板的大小
if (IS_WIN30_DIB (lpbi))
{
//返回颜色数目×RGBQUAD的大小
return (WORD)(DIBNumColors(lpbi) sizeof(RGBQUAD));
}
else
{
//返回颜色数目×RGBTRIPLE的大小
return (WORD)(DIBNumColors(lpbi) sizeof(RGBTRIPLE));
}
}
/
函数名称:
DIBNumColors()
参数:
LPSTR lpbi - 指向DIB对象的指针
返回值:
WORD - 返回调色板中颜色的种数
说明:
该函数返回DIB中调色板的颜色的种数。对于单色位图,返回2,
对于16色位图,返回16,对于256色位图,返回256;对于真彩色
位图(24位),没有调色板,返回0。
/
WORD CDibImage::DIBNumColors(LPSTR lpbi)
{
WORD wBitCount;
// 对于Windows的DIB, 实际颜色的数目可以比象素的位数要少。
// 对于这种情况,则返回一个近似的数值。
// 判断是否是WIN30 DIB
if (IS_WIN30_DIB(lpbi))
{
DWORD dwClrUsed;
dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed; // 读取dwClrUsed值
if (dwClrUsed != 0)
{
// 如果dwClrUsed(实际用到的颜色数)不为0,直接返回该值
return (WORD)dwClrUsed;
}
}
// 读取象素的位数
if (IS_WIN30_DIB(lpbi))
{
wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount; // 读取biBitCount值
}
else
{
wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount; // 读取biBitCount值
}
// 按照象素的位数计算颜色数目
switch (wBitCount)
{
case 1:
return 2;
break;
case 4:
return 16;
break;
case 8:
return 256;
break;
default:
return 0;
break;
}
}
/
函数名称:
CopyHandle()
参数:
HGLOBAL h - 要复制的内存区域
返回值:
HGLOBAL - 复制后的新内存区域
说明:
该函数复制指定的内存区域。返回复制后的新内存区域,出错时返回0。
/
HGLOBAL CDibImage::CopyHandle (HGLOBAL h)
{
if (h == NULL)
{
return NULL;
}
DWORD dwLen = ::GlobalSize((HGLOBAL) h); // 获取指定内存区域大小
HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen); // 分配新内存空间
if (hCopy != NULL) // 判断分配是否成功
{
void lpCopy = ::GlobalLock((HGLOBAL) hCopy);
void lp = ::GlobalLock((HGLOBAL) h);
memcpy(lpCopy, lp, dwLen);
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
}
return hCopy;
}
/
函数名称:
SaveDIB()
参数:
HDIB hDib - 要保存的DIB
CFile& file - 保存文件CFile
返回值:
BOOL - 成功返回TRUE,否则返回FALSE或者CFileException
说明:
该函数将指定的DIB对象保存到指定的CFile中。该CFile由调用程序打开和关闭。
/
BOOL CDibImage::SaveDIB(HDIB hDib, CFile& file)
{
BITMAPFILEHEADER bmfHdr; // Bitmap文件头
LPBITMAPINFOHEADER lpBI; // 指向BITMAPINFOHEADER的指针
DWORD dwDIBSize; // DIB大小
if (hDib == NULL)
{
return FALSE;
}
// 读取BITMAPINFO结构,并锁定
lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
if (lpBI == NULL)
{
return FALSE;
}
// 判断是否是WIN30 DIB
if (!IS_WIN30_DIB(lpBI))
{
// 不支持其它类型的DIB保存
::GlobalUnlock((HGLOBAL) hDib);
return FALSE;
}
////////////////////////////////////////////////////////////////////////
// 填充文件头///////////////////////////////////////////////////////////
bmfHdrbfType = DIB_HEADER_MARKER; // 文件类型"BM"
// 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并
// 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。
// 文件头大小+颜色表大小
// (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)
dwDIBSize = (LPDWORD)lpBI + PaletteSize((LPSTR)lpBI);
// 计算图像大小
if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
{
// 对于RLE位图,没法计算大小,只能信任biSizeImage内的值
dwDIBSize += lpBI->biSizeImage;
}
else
{
DWORD dwBmBitsSize; // 象素的大小
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)((DWORD)lpBI->biBitCount))
lpBI->biHeight; // 大小为Width Height
dwDIBSize += dwBmBitsSize; // 计算出DIB真正的大小
// 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)
lpBI->biSizeImage = dwBmBitsSize;
}
// 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
bmfHdrbfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
// 两个保留字
bmfHdrbfReserved1 = 0;
bmfHdrbfReserved2 = 0;
// 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
bmfHdrbfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
+ PaletteSize((LPSTR)lpBI);
/////////////////////////////////////////////////////////////////////////
// 尝试写文件////////////////////////////////////////////////////////////
TRY
{
fileWrite((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER)); // 写文件头
fileWriteHuge(lpBI, dwDIBSize); // 写DIB头和象素
}
CATCH (CFileException, e)
{
::GlobalUnlock((HGLOBAL) hDib);
THROW_LAST();
}
END_CATCH
::GlobalUnlock((HGLOBAL) hDib);
return TRUE;
}
/
函数名称:
ReadDIBFile()
参数:
CFile& file - 要读取得文件文件CFile
返回值:
HDIB - 成功返回DIB的句柄,否则返回NULL。
说明:
该函数将指定的文件中的DIB对象读到指定的内存区域中。除BITMAPFILEHEADER
外的内容都将被读入内存。
/
HDIB CDibImage::ReadDIBFile(CFile& file)
{
BITMAPFILEHEADER bmfHeader;
HDIB hDIB;
LPSTR pDIB;
DWORD dwBitsSize;
dwBitsSize = fileGetLength(); // 获取DIB(文件)长度(字节)
// 尝试读取DIB文件头
if (fileRead((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
{
return NULL;
}
// 判断是否是DIB对象,检查头两个字节是否是"BM"
if (bmfHeaderbfType != DIB_HEADER_MARKER)
{
return NULL;
}
// 为DIB分配内存
hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
if (hDIB == 0)
{
return NULL;
}
pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
if (fileReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
dwBitsSize - sizeof(BITMAPFILEHEADER) ) // 读象素
{
::GlobalUnlock((HGLOBAL) hDIB);
::GlobalFree((HGLOBAL) hDIB);
return NULL;
}
::GlobalUnlock((HGLOBAL) hDIB);
return hDIB;
}
亮度可以在HSL色彩空间中谈,所以先把由RGB空间转换到HSL空间。
hsl=rgb2hsl(rgb_in),rgb_in即为的RGB空间矩阵。
L分量表示亮度,对的L分量进行两次mean运算,就得到了一张的平均亮度。
批量计算一组的亮度,再求平均值,就得到了这组的亮度平均值。
用平均亮度除以某张的亮度,得一数值,把它乘到这张的L分量上,将越界的数值置为上限,就调整好了这张。再hsl2rgb转换到rgb空间
这段程序主要进行图像处理。
首先转化为灰度图像,画出灰度值分布的直方图。
之后利用sobel算子提取边缘。
之后进行图像腐蚀运算,腐蚀过程中用到的是1;1;1结构,这个结构会腐蚀掉竖着的一些内容不会腐蚀横着的内容。
例如,一个33的矩阵
1,1,1
1,1,1
1,1,1
经过这个算子复试后就会变成
0,0,0
1,1,1
0,0,0
这就保护了被处理图像水平方向的信息。
之后利用矩形5050 进行连接。
最后一个函数bwareaopen是将那些不闭合的区域删掉。
比如字母i,t之类不闭合就会被删掉
o,a闭合就会被保留。
最后就会生成比较完整的边界信息。
close all;clear;clc;
%读取并显示原图
image_rgb=imread('woman1jpg');
image_ycbcr=rgb2ycbcr(image_rgb); %将RGB色彩值变换为YcbCr色彩空间(将RGB真彩色图像转化为YcbCr色彩空间中相等的图像)
y=image_ycbcr(:,:,1); %这三行分别是Ycbcr空间的y,cb,cr对应矩阵
cr=image_ycbcr(:,:,2);
cb=image_ycbcr(:,:,3);
[W,H]=size(y); % y对应矩阵大小
image_face=zeros(W,H); %创建和原图等大的矩阵用来存放接下来二值化人脸数据
%以下循环是根据设定的阈值把人脸转换成二值图像
for x1=1:W; %%%%%%%%(cb=( 100,140),cr=(70,160)这是阈值,这个阈值应该是人脸肤色的范围
for y1=1:H;
if (cb(x1,y1)>=70)&&(cb(x1,y1)<=140)&&(cr(x1,y1)>=80)&&(cr(x1,y1)<=170)
image_face(x1,y1)=0;
else
image_face(x1,y1)=255;
end
end
end
figure(1),imshow(image_face) %显示初步转换成二值图像的人脸
%%%%%%%%% 找到人脸区域并设为白色%%%% (r=35)
se1=strel('square',35); %这个函数可以创建边长35的方形元素
fo=imclose(image_face,se1); %利用上面创建的方形元素,弥补figure(1)中人脸中以及其他部分残留的小块黑色
figure(2),imshow(fo) %显示修补漏洞后的人脸
log=logical(fo); %生成一个逻辑索引矩阵,为非零元素时返回1,否则返回0。用于把figure(2)中黑色部分记录为0,这样对非人脸部分做修改也不会影响人脸
r=image_rgb(:,:,1); %这个是rgb空间三维的数据
g=image_rgb(:,:,2);
b=image_rgb(:,:,3);
r(log==0)=255; %根据前面的逻辑数据把之前的黑色部分对应位置设为255,以后显示RGB图时,非人脸部分就是白色啦
g(log==0)=255;
b(log==0)=255;
face_rgb=cat(3,r,g,b); %把修改后的RGB矩阵重组
figure(3),imshow(face_rgb),title('face_rgb'); % 显示非人脸部分已经转白的RGB图
afm = rgb2gray(face_rgb); % rgb图转灰度图
figure(4), imshow(afm), title('surface image') % 显示人脸灰度图
这个是我个人加的注释 不知道你能不能理解 不能理解可以追问 我们一起学习下 哈哈 我也是新手
最好的也是最实用的方法就是:先打开ps处理软件,打开一张rgb彩图,点击图像——调整——通道混合器命令后打开通道混合器对话框,鼠标点击“单色”标示的方框,此时图像就是一张灰度图了,还可以根据需要调细节,当然还有其他的方法,这种是专业设计人员经常使用的相比于其他的更具有可调细节的功能,
新建一个CImage对象,然后把这个对象的地址作为参数传给RGB2YUV函数
c/c++经常将指针作为参数,用来给函数赋值用的吧
如果你对这种用法不熟悉,可以多看看基础的书籍
数字图像的边界提取:
I=imread('bonemarrtif');
[BW1,th1]=edge(I,'sobel',007);
th1str=num2str(th1)
imshow(I);
title('图1:bonemarrtif原图','fontsize',14,'position',[128,260,0]);
figure;imshow(BW1);
ti='图8: sobel算子提取的边界,阈值为';
ti=strcat(ti,th1str)
title(ti,'fontsize',12,'position',[128,260,0])
图像压缩:
clear
I=imread('blood1tif');
I=im2double(I);
T=dctmtx(8);
B=blkproc(I,[8 8],'P1xP2',T,T);
mask[1,1,1,1,0,0,0,0;1,1,1,0,0,0,0,0;1,1,0,0,0,0,0,0;1,0,0,0,0,0,0,0;0,0,0,0,0,0,0,0;0,0,0,0,0,0,0,0;0,0,0,0,0,0,0,0;0,0,0,0,0,0,0,0;]
B2=(blkproc(B,[8 8],'P1x',mask);
I2=blkproc(I,[8 8],'P1xP2',T,T);
subplot(1,2,1);
imshow(I);title('原图');
subplot(1,2,2);
imshow(I2);title('解压缩图');
以上就是关于求C++图像处理的程序全部的内容,包括:求C++图像处理的程序、求教做图像处理的各位高手:如何让Matlab计算一组RGB图片的亮度平均值并修改图像,得到统一亮度、matlab图像处理程序不懂 求解释等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)