C語(yǔ)言實(shí)現(xiàn)BMP圖像開(kāi)運(yùn)算處理
開(kāi)運(yùn)算可以把比結(jié)構(gòu)元素小的特定圖像細(xì)節(jié)出去,同時(shí)保證不產(chǎn)生全局的幾何失真。濾掉比結(jié)構(gòu)元素小的突刺,切斷細(xì)長(zhǎng)搭接而起到分離作用。
運(yùn)算:用B開(kāi)啟A就是選出了A中某些與B相匹配的點(diǎn),這些點(diǎn)可由完全包含在A中的結(jié)構(gòu)元素B的平移得到。也就是先腐蝕后加膨脹。
#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("open.bmp", "wb");
if (fop == 0)
return 0;
// 定義結(jié)構(gòu)元素
// 腐蝕操作
int t = 0, d = 0, r = 0;
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){
*(pBmpBuf + (i - 1)*lineByte + j) = 0;//下邊的置位1
}
if (t == 0 && r != 0){
*(pBmpBuf + i*lineByte + j + 1) = 0;//右邊的置位1
j = j + 1;
}
}
}
// 膨脹操作
// 初始化
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)
}
}
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é)果分析:效果圖和原圖差別不大。但細(xì)節(jié)如眼睛略微由區(qū)別。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)數(shù)組的循環(huán)移位的方法示例
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)數(shù)組的循環(huán)移位的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
剖析C++中的常量表達(dá)式與省略號(hào)的相關(guān)作用
這篇文章主要介紹了C++中的常量表達(dá)式與省略號(hào)的相關(guān)作用,以及表達(dá)式中的可變參數(shù)模板示例,需要的朋友可以參考下2016-01-01
C++實(shí)現(xiàn)動(dòng)態(tài)規(guī)劃過(guò)程詳解
動(dòng)態(tài)規(guī)劃是解決一類最優(yōu)問(wèn)題的常用方法,它是解決最優(yōu)化問(wèn)題的一種途徑,在本文中,我們將討論如何使用C++實(shí)現(xiàn)動(dòng)態(tài)規(guī)劃算法,并提供一些示例來(lái)幫助您更好地理解該算法2023-05-05
C語(yǔ)言實(shí)現(xiàn)電腦關(guān)機(jī)程序
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)電腦關(guān)機(jī)程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02
C++?opencv實(shí)現(xiàn)在圖片上畫一條線示例代碼
這篇文章主要為大家介紹了C++?opencv實(shí)現(xiàn)在圖片上畫一條線的示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05

