将 24 位".bmp"图像转换为黑白/单色图像的可能算法是什么?
What are possible algorithm for converting a 24-bit ".bmp" image to black and white/Monochrome image?
我正在尝试将彩色24位深度图像转换为单色/blackandwhite image 。因此,有两个部分图像(即(标题(位图文件标头& dib标头(和像素数组
第一部分(标题(。在这里,将单色图像的标头计算为1 的代码,我是否可以计算出其他好方法?
int nBitmapImageWidth = pBMPstructure->fngetBitmapwidth();//Structure which returm the image width
int nRowSize = ((nBitmapImageWidth + 31) / 32) * 4;//Calculation of row size
int nSizeRawBitmap = nRowSize * (pBMPstructure->fngetBitmapheight());
int nSizeBMP = nSizeRawBitmap + 62;
//Bitmap file header starts
bReadBuffer[0] = pBMPstructure->fngetFiletype();
bReadBuffer[2] = nSizeBMP;//Error Debugging
bReadBuffer[6] = pBMPstructure->fngetReserved1();
bReadBuffer[8] = pBMPstructure->fngetReserved2();
bReadBuffer[10] = 0x3E;
//Bitmap file header ends
//DIB Header starts
bReadBuffer[14] = 0x28;
bReadBuffer[18] = nBitmapImageWidth;
bReadBuffer[22] = pBMPstructure->fngetBitmapheight();
bReadBuffer[26] = pBMPstructure->fngetColorplanes(); bReadBuffer[28] = 1;
bReadBuffer[30] = pBMPstructure->fngetCompressionmethod();
bReadBuffer[34] = nSizeRawBitmap;//Error Debugging
bReadBuffer[38] = pBMPstructure->fngetHorizontalresolution();
bReadBuffer[42] = pBMPstructure->fngetVerticalresolution();
bReadBuffer[46] = pBMPstructure->fngetColorpalette();
bReadBuffer[50] = pBMPstructure->fngetImportantcolors();
bReadBuffer[54] = 0x00; bReadBuffer[55] = 0x00; bReadBuffer[56] = 0x00;
bReadBuffer[57] = 0x00;
bReadBuffer[58] = 0xff; bReadBuffer[59] = 0xff;
bReadBuffer[60] = 0xff; bReadBuffer[61] = 0x00;
//DIB Header ends
//End of creating header for black and white
第二部分(像素阵列(。这里是计算像素数组的代码2 3 4。
//Calculation of pixel array for black and white image/Monochrome begins
DWORD bsizeofBMP = pBMPstructure->fngetSizeBMP();
bsizeofBMP -= obj_BMP.fnreturnOffsetpixelarray();
int nSectors = (bsizeofBMP - obj_BMP.fnreturnOffsetpixelarray()) / nLineLengthColoured;
int nFlagHeader = 1, nFlagPixelArray = 1;
if (obj_file_to_read.fnCreate(argv[2], GENERIC_READ, OPEN_EXISTING) == FALSE)//Creating a handle to Source image file
{
dwErrCode = GetLastError();//Retriving the last error code
_tprintf(_T("ntThe error message:-%wsn"), obj_error_handler.fngeterrordescription(dwErrCode));//Retriving error message
_tprintf(_T("ntThe error code:-%d"), obj_error_handler.fngetErrCode());//Retriving error code
_tprintf(_T("n---------------------------------------------------------------------------------------------"));
return EXIT_FAILURE;
}
if (obj_file_to_write.fnCreate(argv[3], GENERIC_WRITE, CREATE_ALWAYS) == FALSE)//Craeting a handle to destination image file
{
dwErrCode = GetLastError();//Retriving the last error code
_tprintf(_T("ntThe error message:-%ws"), obj_error_handler.fngeterrordescription(dwErrCode));//Retriving error message
_tprintf(_T("ntThe error code:-%d"), obj_error_handler.fngetErrCode());//Retriving error code
_tprintf(_T("n---------------------------------------------------------------------------------------------"));
return EXIT_FAILURE;
}
while (nSectors)
{
if (nFlagHeader == 1)//So that pointer goes only one times inside this very code
{
if (obj_file_to_write.fnWrite(bReadBuffer, 62) == FALSE)//To write HEADERS to destination file
{
obj_file_to_write.fnClose();//Closing the handle opened for writing to the file
dwErrCode = GetLastError();//Retriving the last error code
_tprintf(_T("ntThe error message:-%wsn"), obj_error_handler.fngeterrordescription(dwErrCode));//Retriving error message
_tprintf(_T("ntThe error code:-%d"), obj_error_handler.fngetErrCode());//Retriving error code
return EXIT_FAILURE;
}
--nFlagHeader;
}
BYTE bNewReadBuffer[4096] = { 0 };//Creating a new array to load one line of source file
if (nFlagPixelArray == 1)//For first iteration need to set the file pointer to after both headers so that it is not overwritten
{
DWORD dwptr = SetFilePointer(obj_file_to_read.fnGetHandle(), obj_BMP.fnreturnOffsetpixelarray(), NULL, FILE_BEGIN);//SetFilePointer WinAPI
if (dwptr == INVALID_SET_FILE_POINTER)//Check if it is pointing to the desired or giving some garbage value
{
dwErrCode = GetLastError();//Retriving the last error code
_tprintf(_T("ntThe error message:-%wsn"), obj_error_handler.fngeterrordescription(dwErrCode));//Retriving error message
_tprintf(_T("ntThe error code:-%d"), obj_error_handler.fngetErrCode());//Retriving error code
return EXIT_FAILURE;
}
--nFlagPixelArray;//Decrementing so that it will no enter in this part of code
}
if (obj_file_to_read.fnRead(bNewReadBuffer, nLineLengthColoured) == FALSE)
{
obj_file_to_read.fnClose();
obj_file_to_write.fnClose();
dwErrCode = GetLastError();//Retriving the last error code
_tprintf(_T("ntThe error message:-%wsn"), obj_error_handler.fngeterrordescription(dwErrCode));
_tprintf(_T("ntThe error code:-%d"), obj_error_handler.fngetErrCode());//Retriving error code
_tprintf(_T("n---------------------------------------------------------------------------------------------"));
return EXIT_FAILURE;
}
BYTE bMonoBuffer[128] = { 0 };//It is the buffer which is made for storing single line of black and white image
int nMonoBytes = ((nLineLengthColoured - nPaddingColoured) / 3) / (nLineLengthBlackAndWhite - nPaddingBlackAndWhite);//3 is BGR values and calculating rthe sectors
int nMonoAdditional = ((nLineLengthColoured - nPaddingColoured) / 3) % (nLineLengthBlackAndWhite - nPaddingBlackAndWhite);//Calculating the additional bytes which is remaining after calculating the sectors
int nIteratorbNewReadBuffer = 0;
while (nMonoBytes)//nMonoBytes specifies how many times will the bMonoBuffer will be filled
{
for (int i = 0; i < (nLineLengthBlackAndWhite - nPaddingBlackAndWhite); i++)//Loop started for the amount of 1 line which is to be feeded inside the monochrome image
{
bMonoBuffer[i] = (bNewReadBuffer[nIteratorbNewReadBuffer] + bNewReadBuffer[nIteratorbNewReadBuffer + 1] + bNewReadBuffer[nIteratorbNewReadBuffer + 2]) / 3;//Algorithm for conversion from bgr value to monochrome/black ad white i.e the average of all the three value
nIteratorbNewReadBuffer += 3;//Incrementing the iterator for bNewReadBuffer which is containg one single line of coloured BMP
}
if (nPaddingBlackAndWhite != 0)//if padding of black and whiote is not zero
{
for (int i = (nLineLengthBlackAndWhite - nPaddingBlackAndWhite); i < nLineLengthBlackAndWhite; i++)//from the position where data of black and white image ends
{
bMonoBuffer[i] = 00;
}
}
if (obj_file_to_write.fnWrite(bMonoBuffer, nLineLengthBlackAndWhite) == FALSE)
{
obj_file_to_read.fnClose();
obj_file_to_write.fnClose();
dwErrCode = GetLastError();//Retriving the last error code
_tprintf(_T("ntThe error message:-%wsn"), obj_error_handler.fngeterrordescription(dwErrCode));//Retriving error message
_tprintf(_T("ntThe error code:-%d"), obj_error_handler.fngetErrCode());//Retriving error code
_tprintf(_T("n---------------------------------------------------------------------------------------------"));
return EXIT_FAILURE;
}
nMonoBytes--;
}
if (nMonoAdditional != 0)//The remaining bytes
{//Problem here is that the last remaining bytes will be of certain bytes and will be copied to destination but when next iteration starts it will continue
//to convert the whole line for monobytes instead it should be the new bytes have to be readed minus the additional one already readed..
for (int i = 0; i < nMonoAdditional; i++)
{
bMonoBuffer[i] = (bNewReadBuffer[nIteratorbNewReadBuffer] + bNewReadBuffer[nIteratorbNewReadBuffer + 1] + bNewReadBuffer[nIteratorbNewReadBuffer + 2]) / 3;
}
nMonoAdditional--;
}
nSectors--;
}
例如(.bmp image(
假设有大小的彩色图像 1,131,654字节,并且众所周知, 54个字节将是 headers 小。当我从图像大小中减去标头零件时,彩色的像素阵列大小为 1,131,600字节,并且可以进行一些 padding bytes ,让假设有色的填充是3个字节和一行彩色图像的长度为 2460字节,图像中的总线将为 460行。所需的图像是单色图像> 104字节和填充字节的线元素是 2个字节 ..,将有 2457/3 = 819 BGR Pairs 表示如果我将每对写入所需的文件(即黑色和白色(,那么它将采用 819 Pairs * 460行= 3,76,740字节,但所需的文件应为 47,840 62 = 47,902 size !!
- 首先,在1图中调试389和399的错误。如果是的,有什么比这更好的方法?
- 第二件事第二,这里的问题是剩下的字节将是一定的字节,并且将被复制到目的地,但是当下一个迭代开始时,它将继续转换单循环的整个行,而应该是新字节必须是新字节被读取减去已经读过的其他一个。
- 除了平均少于黑白外,什么是将颜色转换为黑白的算法。
预先感谢
好吧,这里有很多问题,由于缺乏上下文,其中大多数是无法回答的。我唯一可以回答的是为什么您的图像数据大小为376,740字节,而不是47,840字节。
376,740字节与每个像素1个字节(= 8位(的819x460单色/灰度图像一致。但是,当我们谈论"黑白"图像时,我们通常是指每个像素的1 。每行819位为我们提供819/8 = 102.375字节每扫描线。每次扫描线上获得104个字节,均达到了偶数的字节。乘以460个扫描线,我们获得了47,840字节的图像数据。
- 卤化物:较大图像的去马赛克算法错误.似乎适用于 16x16 图像
- 更快的图像镜像算法
- 将 24 位".bmp"图像转换为黑白/单色图像的可能算法是什么?
- C++ 图像过滤算法
- 优化的图像卷积算法
- OPENCV:如何使用5点算法从来自不同相机的两个图像之间的特征匹配来计算必需矩阵
- 用于在黑白图像上查找未连接区域(岛屿)的算法
- 有没有一种算法可以使用opencv来分离图像的前景和背景
- 提高准确性的最佳图像匹配算法
- openCV立体匹配算法(立体BM和立体SGBM)是否可以处理垂直校正图像
- 将中值剪切颜色缩减算法的输出调色板应用于源图像
- 基于图像的计数算法,用于对移动输送机上的物体进行计数
- visualc++洪水填充图像递归算法错误
- 如何在opencv中使用surf算法在源图像中找到模板图像的确切角
- 快速的数据结构或算法来找到图像堆栈中每个像素的平均值
- 将图像转换为有限大小的调色板的好算法是什么?
- 寻找单图像HDR算法
- 图像水平调整算法
- 我应该如何去实现算法与黑白和彩色图像使用
- 我可以使用什么算法来优化图像选择蒙版