C++ 位图二值化处理代码解析 - ImageProcesTwoValue 类
这段代码定义了一个名为 'ImageProcesTwoValue' 的类,该类继承自 'ImageProcesService' 类。其中,'ImageProcesTwoValue' 类实现了 'ImageProces' 方法,用于对位图进行二值化处理。在该方法中,首先从传入的 'data' 中获取位图文件头、位图信息头和调色板信息等数据,然后根据位图的宽度和高度计算出每行数据的字节数,创建一个与位图大小相同的缓存区 'pBmpBuf',并将位图数据拷贝到该缓存区中。
接下来,将位图的调色板信息修改为 256 色调色板,并将其拷贝到 'data' 中。然后,将位图数据进行灰度化处理,将灰度化后的数据重新放置到缓存区 'pBmpBuf1' 中。最后,计算出位图的平均灰度值,并根据该值将缓存区 'pBmpBuf1' 中的数据进行二值化处理,处理结果放置到 'data' 中。除此之外,该代码中还定义了一个 'ImageProcesTwoValueBundleActivator' 类,用于在程序启动时注册 'ImageProcesTwoValue' 服务。
以下是代码的详细解释:
ImageProcesTwoValue 类
-
ImageProces 方法
- 从 'data' 中读取位图文件头、信息头和调色板数据。
- 计算每行数据的字节数并创建缓存区 'pBmpBuf',并将位图数据拷贝到缓存区中。
- 将位图调色板信息修改为 256 色并拷贝到 'data' 中。
- 将位图数据进行灰度化处理,并将灰度化后的数据拷贝到缓存区 'pBmpBuf1' 中。
- 计算位图的平均灰度值。
- 根据平均灰度值进行二值化处理,并将结果拷贝回 'data' 中。
-
type 方法
- 返回当前类的类型信息。
-
isA 方法
- 检查当前类是否为指定类型。
ImageProcesTwoValueBundleActivator 类
-
start 方法
- 创建 'ImageProcesTwoValue' 对象。
- 使用 'BundleContext' 对象注册 'ImageProcesTwoValue' 服务。
-
stop 方法
- 使用 'BundleContext' 对象注销 'ImageProcesTwoValue' 服务。
代码示例:
class ImageProcesTwoValue : public ImageProcesService
{
public:
ImageProcesTwoValue() {}
~ImageProcesTwoValue() {}
unsigned long ImageProces(void *data)
{
BITMAPFILEHEADER bfhead;
BITMAPINFOHEADER bihead;
RGBQUAD *pColorTable;
memcpy(&bfhead, data, 14); //灏嗘枃浠跺ご璇诲叆鍐呭瓨
memcpy(&bihead, data+14, 40); //灏嗕俊鎭ご璇诲叆鍐呭瓨
int LineByte=(bihead.biWidth*24/8+3)/4*4; //淇濊瘉姣忚瀛楄妭鏁颁负4鐨勬暣鏁板€�
unsigned char *pBmpBuf=new unsigned char[LineByte*bihead.biHeight]; //涓烘暟鎹尯鍒嗛厤鍐呭瓨绌洪棿
memcpy(pBmpBuf, data+54, LineByte*bihead.biHeight); //灏哹mp鏁版嵁鍖鸿鍏ュ唴瀛�
//鐜板皢鐪熷僵鍥剧伆搴﹀寲
int LineByte1=(bihead.biWidth*8/8+3)/4*4; //鐢变簬鐏板害鍖栧悗姣忓儚绱犱綅鏁板彉涓�8锛屾墍浠ユ瘡琛屽瓧鑺傛暟鍙戠敓鏀瑰彉锛屼絾浠嶈姹備负4鐨勬暣鏁板€�
//鏇存敼鏂囦欢澶达紝骞跺皢鍏朵繚瀛�
bfhead.bfSize=14+40+sizeof(RGBQUAD)*256+LineByte1*bihead.biHeight; //鏇存敼鏂囦欢澶у皬
bfhead.bfOffBits=14+40+sizeof(RGBQUAD)*256; //鏇存敼鍋忕Щ鍊�
memcpy(data, &bfhead, 14);
//鏇存敼淇℃伅澶村苟灏嗗叾淇濆瓨
bihead.biBitCount=8; //鏇存敼姣忓儚绱犱綅鏁�
bihead.biSizeImage=LineByte1*bihead.biHeight; //鏇存敼鏁版嵁鍖哄ぇ灏�
memcpy(data+14, &bihead,40);
//鍥犱负鐏板害鍖栧浘鍍忔湁棰滆壊琛紝鎵€浠ュ垱寤洪鑹茶〃骞朵繚瀛�
pColorTable=new RGBQUAD[256];
for(int i=0;i<256;i++)
pColorTable[i].rgbRed = pColorTable[i].rgbGreen = pColorTable[i].rgbBlue = i;//浣块鑹茶〃涓瘡绉嶉鑹茬殑R,G,B鍒嗛噺鐩哥瓑涓旂瓑浜庣储寮曞€�
memcpy(data+54, pColorTable, sizeof(RGBQUAD)*256);
//鏀瑰彉鏁版嵁鍖�
unsigned char *pBmpBuf1 = new unsigned char[LineByte1*bihead.biHeight];
for(int i=0;i<bihead.biHeight;i++)
for(int j=0;j<bihead.biWidth;j++)
{
unsigned char *pb1,*pb2;
pb1=pBmpBuf+i*LineByte+j*3;
int y=*(pb1)*0.299+*(pb1+1)*0.587+*(pb1+2)*0.114;
pb2=pBmpBuf1+i*LineByte1+j;
*pb2=y;
}
//浜屽€煎寲鏂规硶涓€锛氶槇鍊艰涓�127锛岀伆搴﹀€煎皬浜�127鐨勭疆闆讹紝鍏朵粬鐨勭疆涓�255锛�
//for(int i=0;i<bihead.biHeight;i++)
// for(int j=0;j<bihead.biWidth;j++)
// {
// unsigned char *pb;
// pb=pBmpBuf1+i*LineByte1+j;
// if(*pb<127) //灏嗘瘡涓儚绱犲€间笌127姣旇緝
// *pb=0;
// else
// *pb=255;
// }
//鏂规硶浜�:璁$畻鍍忕礌鐨勫钩鍧囧€糑锛屾壂鎻忓浘鍍忕殑姣忎釜鍍忕礌鍊煎鍍忕礌鍊煎ぇ浜嶬鍍忕礌鍊艰涓�255(鐧借壊)锛屽€煎皬浜庣瓑浜嶬鍍忕礌鍊艰涓�0(榛戣壊)
int y=0;//鍍忕礌鍜�
int k=0;//鍍忕礌涓暟
for(int i=0;i<bihead.biHeight;i++)
for(int j=0;j<bihead.biWidth;j++)
{
unsigned char *pb;
pb=pBmpBuf1+i*LineByte1+j;
y=y+*pb; //璁$畻鎵€鏈夊儚绱犵伆搴﹀€间箣鍜�
k++; //缁熻鍍忕礌涓暟
}
y=y/k; //姹傚儚绱犲钩鍧囧€�
for(int i=0;i<bihead.biHeight;i++)
for(int j=0;j<bihead.biWidth;j++)
{
unsigned char *pb1;
pb1=pBmpBuf1+i*LineByte1+j;
if(*pb1<y) //灏嗘瘡涓儚绱犲€间笌骞冲潎鍊间綔姣旇緝
*pb1=0;
else
*pb1=255;
}
memcpy(data+54+sizeof(RGBQUAD)*256, pBmpBuf1,LineByte1*bihead.biHeight);
return (unsigned long)bfhead.bfSize;
}
const std::type_info& type() const
{
return typeid(ImageProcesService);
}
bool isA(const std::type_info& otherType) const
{
std::string name(typeid(ImageProcesService).name());
return name == otherType.name() || TsingHua::TMPP::Service::isA(otherType);
}
};
class ImageProcesTwoValueBundleActivator: public TsingHua::TMPP::BundleActivator
{
private:
TsingHua::TMPP::ServiceRef::Ptr _pService;
TsingHua::TMPP::Service::Ptr pService;
public:
void start(TsingHua::TMPP::BundleContext::Ptr pContext)
{
if (pService.isNull()) {
pService = new ImageProcesTwoValue();
}
_pService = pContext->registry().registerService(_IMAGE_PROCES_SERVICE_, pService, TsingHua::TMPP::Properties());
}
void stop(TsingHua::TMPP::BundleContext::Ptr pContext)
{
pContext->registry().unregisterService(_pService);
}
};
原文地址: https://www.cveoy.top/t/topic/oCnU 著作权归作者所有。请勿转载和采集!