C語(yǔ)言實(shí)現(xiàn)BMP圖像閉運(yùn)算處理
閉運(yùn)算可以把比結(jié)構(gòu)元素小的特定圖像細(xì)節(jié)出去,同時(shí)保證不產(chǎn)生全局的幾何失真。填充比結(jié)構(gòu)元素小的缺口或孔,搭接短的間斷而起到連接作用。
運(yùn)算:也就是先膨脹后腐蝕。
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
int main(int* argc, char** argv)
{
FILE* fp = fopen("./threshold.bmp", "rb");
if (fp == 0)
return 0;
BITMAPFILEHEADER fileHead;
fread(&fileHead, sizeof(BITMAPFILEHEADER), 1, fp);
BITMAPINFOHEADER infoHead;
fread(&infoHead, sizeof(BITMAPINFOHEADER), 1, fp);
int width = infoHead.biWidth;
int height = infoHead.biHeight;
int biCount = infoHead.biBitCount;
int lineByte = (biCount*width / 8 + 3) / 4 * 4;
RGBQUAD* pColorTable;
pColorTable = new RGBQUAD[256];
fread(pColorTable, sizeof(RGBQUAD), 256, fp);
unsigned char* pBmpBuf;
pBmpBuf = new unsigned char[lineByte*height];
fread(pBmpBuf, lineByte*height, 1, fp);
fclose(fp);
// 新圖
FILE* fop = fopen("close.bmp", "wb");
if (fop == 0)
return 0;
// 膨脹操作
// 初始化
int t = 0, d = 0, r = 0;
unsigned char* pBmpBuf2;
pBmpBuf2 = new unsigned char[lineByte*height];
for (int i = 0; i < height; ++i){
for (int j = 0; j < width; ++j){
*(pBmpBuf2 + i*lineByte + j) = 255;
}
}
for (int i = 1; i < height; ++i){
for (int j = 0; j < width - 1; ++j){
t = *(pBmpBuf + i*lineByte + j); // 當(dāng)前點(diǎn)
d = *(pBmpBuf + (i - 1)*lineByte + j); // 下面點(diǎn)
r = *(pBmpBuf + i*lineByte + j + 1); // 右邊點(diǎn)
if (t == 0 && d == 0 && r == 0){
*(pBmpBuf2 + i*lineByte + j) = 0; // 當(dāng)前點(diǎn)
}
}
}
// 結(jié)構(gòu)元素向上反轉(zhuǎn)180度,對(duì)最下面一排處理
for (int j = 0; j < width - 1; ++j){
t = *(pBmpBuf + j); // 當(dāng)前點(diǎn)
d = *(pBmpBuf + lineByte + j); // 上面點(diǎn)
r = *(pBmpBuf + j + 1); // 右邊點(diǎn)
if (t == 0 && d == 0 && r == 0){
*(pBmpBuf2 + j) = 0; // 當(dāng)前點(diǎn)
}
}
// 結(jié)構(gòu)元素向右反轉(zhuǎn),對(duì)最右邊一列處理
for (int i = 1; i < height; ++i){
t = *(pBmpBuf + i*lineByte + width - 1);
d = *(pBmpBuf + (i - 1)*lineByte + width - 1);
r = *(pBmpBuf + i*lineByte + width - 2);
if (t == 0 && d == 0 && r == 0){
*(pBmpBuf2 + i*lineByte + width - 1) = 0; // 當(dāng)前點(diǎn)
}
}
// 腐蝕操作
for (int i = 1; i < height; ++i){
for (int j = 0; j < width - 1; ++j){
t = *(pBmpBuf2 + i*lineByte + j); // 當(dāng)前點(diǎn)
d = *(pBmpBuf2 + (i - 1)*lineByte + j); // 下面點(diǎn)
r = *(pBmpBuf2 + i*lineByte + j + 1); // 右邊點(diǎn)
if (t == 0 && d != 0){
*(pBmpBuf2 + (i - 1)*lineByte + j) = 0;//下邊的置位1
}
if (t == 0 && r != 0){
*(pBmpBuf2 + i*lineByte + j + 1) = 0;//右邊的置位1
j = j + 1;
}
}
}
fwrite(&fileHead, sizeof(BITMAPFILEHEADER), 1, fop);
fwrite(&infoHead, sizeof(BITMAPINFOHEADER), 1, fop);
fwrite(pColorTable, sizeof(RGBQUAD), 255, fop);
fwrite(pBmpBuf2, lineByte*height, 1, fop);
fclose(fop);
system("pause");
return 0;
}
實(shí)驗(yàn)結(jié)果:
實(shí)驗(yàn)結(jié)果分析:原圖和效果圖略微由區(qū)別。但效果圖似乎和開(kāi)運(yùn)算相反了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++類(lèi)的定義和對(duì)象的創(chuàng)建詳解
本篇文章重點(diǎn)講解了兩種創(chuàng)建對(duì)象的方式:一種是在棧上創(chuàng)建,形式和定義普通變量類(lèi)似;另外一種是在堆上使用 new 關(guān)鍵字創(chuàng)建,必須要用一個(gè)指針指向它,下面和小編一起來(lái)學(xué)習(xí)下面為文章的內(nèi)容2021-09-09
C語(yǔ)言實(shí)現(xiàn)通訊錄系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)通訊錄系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
關(guān)于函數(shù)傳參問(wèn)題(指針傳參,值傳參,引用傳參)
這篇文章主要介紹了關(guān)于函數(shù)傳參問(wèn)題(指針傳參,值傳參,引用傳參),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01

