#include "windows.h"
#include <stdio.h>
#include <math.h>
unsigned char *pBmpBuf;
int bmpWidth;
int bmpHeight;
RGBQUAD *pColorTable;
int biBitCount;
unsigned char *pNewBmpBuf;
/****************************************************
* readBmp()
* char *bmpName 文件名字及路径
* 函数功能:读取图像
*****************************************************/
bool readBmp(char *bmpName)
{
FILE *fp = fopen(bmpName, "rb");
if (fp == 0)
{
return 0;
}
fseek(fp, sizeof(BITMAPFILEHEADER),0);
BITMAPINFOHEADER head;
fread(&head, sizeof(BITMAPINFOHEADER), 1, fp);
bmpWidth = head.biWidth;
bmpHeight = head.biHeight;
biBitCount = head.biBitCount;
int lineByte =(bmpWidth*biBitCount/8 + 3)/4*4;
if (biBitCount == 8)
{
pColorTable = new RGBQUAD[256]; /////////
fread(pColorTable, sizeof(RGBQUAD), 256, fp);
}
pBmpBuf = new unsigned char[lineByte * bmpHeight];
fread(pBmpBuf, 1, lineByte*bmpHeight, fp);
fclose(fp);
return 1;
}
/********************************************************************
* saveBMP()
* 函数功能:保存图像
********************************************************************/
bool saveBMP(char *bmpName, unsigned char *imgBuf, int width, int height, int biBitCount, RGBQUAD *pColorTable)
{
if (!imgBuf)
{
return 0;
}
int colorTablesize = 0;
if (biBitCount == 8)
{
colorTablesize = 1024;
}
int lineByte = (width*biBitCount/8 + 3)/4*4;
FILE *fp = fopen(bmpName, "wb");
if (fp == 0)
{
return 0;
}
BITMAPFILEHEADER fileHead;
fileHead.bfType = 0x4D42;
fileHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + colorTablesize + lineByte*height;
fileHead.bfReserved1 = 0;
fileHead.bfReserved2 = 0;
fileHead.bfOffBits = 54 + colorTablesize;
fwrite(&fileHead, sizeof(BITMAPFILEHEADER), 1, fp);
BITMAPINFOHEADER head;
head.biBitCount = biBitCount;
head.biClrImportant = 0;
head.biClrUsed = 0;
head.biCompression =0;
head.biHeight = height;
head.biPlanes = 1;
head.biSize = 40;
head.biSizeImage = lineByte*height;
head.biWidth = width;
head.biXPelsPerMeter = 0;
head.biYPelsPerMeter = 0;
fwrite(&head, sizeof(BITMAPINFOHEADER), 1, fp);
if (biBitCount == 8)
{
fwrite(pColorTable, sizeof(RGBQUAD), 256, fp); //??????
}
fwrite(imgBuf, lineByte*height, 1, fp);
fclose(fp);
return 1;
}
/********************************************************************
* grayBmp()
* 函数功能:灰度函数,使图像灰度化
********************************************************************/
bool grayBmp(char *bmpName, int width, int height)
{
int i, j, k;
int lineByte = (width*biBitCount/8 + 3)/4*4;
if (biBitCount == 8)
{
return 0;
}
if (biBitCount == 24)
{
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
for (k=0; k<3; k++)
{
// R = B = G
if (k==0)
{
*(pBmpBuf + i*lineByte + j*3);
}
else if (k==1)
{
*(pBmpBuf + i*lineByte + j*3 +k) = *(pBmpBuf + i*lineByte + j*3);
}
else
{
*(pBmpBuf + i*lineByte + j*3 +k) = *(pBmpBuf + i*lineByte + j*3);
}
}
}
}
}
return 1;
}
/********************************************************************
* grayTo8bit()
* 函数功能:灰度函数转化为8位图像
********************************************************************/
bool grayTobit8(char *bmpName, int width, int height)
{
if (biBitCount == 8)
{
return 0;
}
//新生成的8位图像
int lineByteNew =((width/3)*biBitCount/8 + 3)/4*4;
int line = (width*biBitCount/8 + 3)/4*4;
pNewBmpBuf = new unsigned char[lineByteNew * height];
for (int i=0; i<height; i++)
{
for (int j=0; j<width; j++)
{
*(pNewBmpBuf + i*lineByteNew + j) = *(pBmpBuf + i*line + 3*j); //line为lineByteNew的3倍
}
}
//得到一个新的8为缓存pNewBmpBuf
return 1;
}
bool bit8Tobit24(unsigned char *imgBuf, int width, int height)
{
int lineByteNew =((width/3)*biBitCount/8 + 3)/4*4;
int line = (width*biBitCount/8 + 3)/4*4;
//恢复为24位
for (int i=0; i<height; i++)
{
for (int j=0; j<width; j++)
{
for (int k=0; k<3; k++)
{
*(pBmpBuf + i*line + j*3 + k) = *(imgBuf + i*lineByteNew + j); ////line为lineByteNew的3倍
}
}
}
return 1;
}
bool Threshold(unsigned char *imgBuf, int width, int height)
{
int lineByte = ((width/3)*biBitCount/8 + 3)/4*4;
for (int i=0; i<height; i++)
{
for (int j=0; j<width; j++)
{
if (*(imgBuf + i*lineByte + j)>118)
{
*(imgBuf + i*lineByte + j) = 255;
}
else
{
*(imgBuf + i*lineByte + j)=0;
}
}
}
return 1;
}
bool Filtering(unsigned char *imgBuf, int width, int height)
{
int i, j;
int lineByte = ((width/3)*biBitCount/8 + 3)/4*4;
int averg;
for (i=1; i<height-1; i++)
{
for (j=1; j<width-1; j++)
{
averg = ((*(imgBuf + (i-1)*lineByte + (j-1))) + (*(imgBuf + (i-1)*lineByte + j)) + (*(imgBuf + (i-1)*lineByte + (j+1))) + (*(imgBuf + i*lineByte + (j-1))) + (*(imgBuf + i*lineByte + (j+1))) + (*(imgBuf + (i+1)*lineByte + j-1)) + *(imgBuf + (i+1)*lineByte + j) + *(imgBuf + (i+1)*lineByte + j+1))/8 ;
if (abs(averg - (*(imgBuf + i*lineByte + j)))>127.5)
{
*(imgBuf + i*lineByte + j) = averg;
}
}
}
return 1;
}
//hough transform
void Hough(unsigned char *imgBuf, int width, int height, int *pR, int *pTh, int iThreshold)
{
int *pArray;
int iRMax = (int)sqrt(width*width + height*height) + 1; //图像对角线加1
int iThMax = 361;
int iTh = 0;
int iR;
int iMax = -1;
int iThMaxIndex = -1;
int iRMaxIndex = -1;
double PI=3.14;
pArray = new int[iRMax * iThMax];
memset(pArray, 0, sizeof(int)*iRMax*iThMax);
float fRate = (float)(PI/180);
for (int y=0; y<height; y++)
{
for (int x=0; x<width; x++)
{
if (*imgBuf = 255)
{
for (iTh=0; iTh<iThMax; iTh+=1)
{
iR = (int)(x*cos(iTh * fRate)+y*sin(iTh*fRate));
if (iR>0)
{
pArray[iR/1*iThMax+iTh]++;
}
}
}
imgBuf++;
}
}
for (iR=0; iR<iThMax; iTh++)
{
int iCount=pArray[iR*iThMax+iTh];
if (iCount>iMax)
{
iMax=iCount;
iRMaxIndex=iR;
iThMaxIndex=iTh;
}
}
if (iMax>=iThreshold)
{
*pR=iRMaxIndex;
*pTh=iThMaxIndex;
}
delete []pArray;
return;
} //end of hough
void main()
{
char readPath[] = "33.bmp"; /* 读图像 */
readBmp(readPath);
grayBmp(readPath, bmpWidth, bmpHeight); /* 灰度化 */
char writePath[] = "灰度化图.bmp";
saveBMP(writePath, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable); /* 灰度化后保存图像 */
grayTobit8("灰度化图.bmp", bmpWidth, bmpHeight); //24转8位
Threshold(pNewBmpBuf, bmpWidth, bmpHeight); //二值化
bit8Tobit24(pNewBmpBuf, bmpWidth, bmpHeight); //8位变24位
saveBMP("二值图.bmp", pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable); //保存二值图像
Filtering(pNewBmpBuf, bmpWidth, bmpHeight); //滤波函数
bit8Tobit24(pNewBmpBuf, bmpWidth, bmpHeight);
saveBMP("滤波后.bmp", pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable);
//hough transform detection parallel line
// Hough(pBmpBuf, bmpWidth, bmpHeight,)
delete pNewBmpBuf;
delete pBmpBuf;
//24位图转8位图
//Threshold
}