自适应阈值分割(vc实现)

来源:互联网 发布:香港政府医院预约软件 编辑:程序博客网 时间:2024/05/21 17:31

1.以8×8邻域

划分太细,整体效果像铅笔素描。

void CISLSView::OnThresholdAdaptive88(){//程序编制:李立宗//lilizong@gmail.com//2012-8-14if(myImage1.IsNull())OnOpenResourceFile();if(!myImage2.IsNull())myImage2.Destroy();if(myImage2.IsNull()){myImage2.Create(myImage1.GetWidth(),myImage1.GetHeight(),24,0);}if(myImage3.IsNull()){myImage3.Create(myImage1.GetWidth(),myImage1.GetHeight(),24,0);}//COLORREF pixel; int maxY = myImage1.GetHeight();int maxX=myImage1.GetWidth();byte* pRealData;byte* pRealData2;byte* pRealData3;pRealData=(byte*)myImage1.GetBits();pRealData2=(byte*)myImage2.GetBits();pRealData3=(byte*)myImage3.GetBits();int pit=myImage1.GetPitch();int pit2=myImage2.GetPitch();int pit3=myImage3.GetPitch();//需要注意,pit和pit2的值并不一样,所以如果使用一个值,会导致不同的结果出现//CString str;//str.Format(TEXT("%d"),pit);//MessageBox(str);//str.Format(TEXT("%d"),pit2);//MessageBox(str);int bitCount=myImage1.GetBPP()/8;int bitCount2=myImage2.GetBPP()/8;int bitCount3=myImage3.GetBPP()/8;int tempR,tempG,tempB;//float temp,tempX,tempY;int temp;int T=128;//int pixel[4];float u0,u1;   //均值float w0,w1;   //概率float sum0,sum1;  //像素和int optIndex,optT;   //最优阈值,及其所在像素的值float fVaria,fMaxVaria=0;   //临时方差,最大方差int i;        //循环变量//int pixelR[256],pixelG[256],pixelB[256];int pixel[256]={0};   //不要忘记初始化//灰度化for (int y=0; y<maxY; y++) {for (int x=0; x<maxX; x++) {temp=*(pRealData+pit*(y)+(x)*bitCount);if(bitCount==3){tempR=*(pRealData+pit*(y)+(x)*bitCount);tempG=*(pRealData+pit*(y)+(x)*bitCount+1);tempB=*(pRealData+pit*(y)+(x)*bitCount+2);temp=(int)(tempR*0.49+tempG*0.31+tempB*0.2);//temp=(int)((tempR+tempG+tempB)/3);}*(pRealData3+pit3*(y)+(x)*bitCount3)=temp;*(pRealData3+pit3*(y)+(x)*bitCount3+1)=temp;*(pRealData3+pit3*(y)+(x)*bitCount3+2)=temp;}}//计算除边界外的点for (int y=1; y<maxY-1; y++) {for (int x=1; x<maxX-1; x++) {temp=*(pRealData3+pit3*(y)+(x)*bitCount3);T=*(pRealData3+pit3*(y-1)+(x-1)*bitCount3)+*(pRealData3+pit3*(y-1)+(x)*bitCount3)+*(pRealData3+pit3*(y-1)+(x+1)*bitCount3)+*(pRealData3+pit3*(y)+(x-1)*bitCount3)+*(pRealData3+pit3*(y)+(x)*bitCount3)+*(pRealData3+pit3*(y)+(x+1)*bitCount3)+*(pRealData3+pit3*(y+1)+(x-1)*bitCount3)+*(pRealData3+pit3*(y+1)+(x)*bitCount3)+*(pRealData3+pit3*(y+1)+(x+1)*bitCount3);T=(int)(T/9.0);//CString str;//str.Format(TEXT("%d"),T);//MessageBox(str);if(temp>T)temp=255;elsetemp=0;*(pRealData2+pit2*(y)+(x)*bitCount2)=temp;*(pRealData2+pit2*(y)+(x)*bitCount2+1)=temp;*(pRealData2+pit2*(y)+(x)*bitCount2+2)=temp;}}Invalidate();}

2.将图像划分为四个区域计算

该模式缺点,可以看到四个区域之间具有明显的边界。

void CISLSView::OnThresholdAdaptive41(){//程序编制:李立宗 lilizong@gmail.com//2012-8-14if(myImage1.IsNull())OnOpenResourceFile();if(!myImage2.IsNull())myImage2.Destroy();if(myImage2.IsNull()){myImage2.Create(myImage1.GetWidth(),myImage1.GetHeight(),24,0);}if(myImage3.IsNull()){myImage3.Create(myImage1.GetWidth(),myImage1.GetHeight(),24,0);}//COLORREF pixel; int maxY = myImage1.GetHeight();int maxX=myImage1.GetWidth();byte* pRealData;byte* pRealData2;byte* pRealData3;pRealData=(byte*)myImage1.GetBits();pRealData2=(byte*)myImage2.GetBits();pRealData3=(byte*)myImage3.GetBits();int pit=myImage1.GetPitch();int pit2=myImage2.GetPitch();int pit3=myImage3.GetPitch();//需要注意,pit和pit2的值并不一样,所以如果使用一个值,会导致不同的结果出现//CString str;//str.Format(TEXT("%d"),pit);//MessageBox(str);//str.Format(TEXT("%d"),pit2);//MessageBox(str);int bitCount=myImage1.GetBPP()/8;int bitCount2=myImage2.GetBPP()/8;int bitCount3=myImage3.GetBPP()/8;int tempR,tempG,tempB;//float temp,tempX,tempY;int temp;int T=128;//int pixel[4];float u0,u1;   //均值float w0,w1;   //概率float sum0,sum1;  //像素和int optIndex,optT;   //最优阈值,及其所在像素的值float fVaria,fMaxVaria=0;   //临时方差,最大方差int i;        //循环变量//int pixelR[256],pixelG[256],pixelB[256];int pixel[256]={0};   //不要忘记初始化int sum=0,avg;//灰度化for (int y=0; y<maxY; y++) {for (int x=0; x<maxX; x++) {temp=*(pRealData+pit*(y)+(x)*bitCount);if(bitCount==3){tempR=*(pRealData+pit*(y)+(x)*bitCount);tempG=*(pRealData+pit*(y)+(x)*bitCount+1);tempB=*(pRealData+pit*(y)+(x)*bitCount+2);temp=(int)(tempR*0.49+tempG*0.31+tempB*0.2);//temp=(int)((tempR+tempG+tempB)/3);}*(pRealData3+pit3*(y)+(x)*bitCount3)=temp;*(pRealData3+pit3*(y)+(x)*bitCount3+1)=temp;*(pRealData3+pit3*(y)+(x)*bitCount3+2)=temp;}}//计算左上角阈值for (int y=0; y<maxY/2; y++) {for (int x=0; x<maxX/2; x++) {sum+=*(pRealData3+pit3*(y)+(x)*bitCount3);}}avg=(int)(sum/(maxY/2*(maxX/2)));//处理左上角for (int y=0; y<maxY/2; y++) {for (int x=0; x<maxX/2; x++) {temp=*(pRealData3+pit3*(y)+(x)*bitCount3);if(temp>avg)temp=255;elsetemp=0;*(pRealData2+pit2*(y)+(x)*bitCount2)=temp;*(pRealData2+pit2*(y)+(x)*bitCount2+1)=temp;*(pRealData2+pit2*(y)+(x)*bitCount2+2)=temp;}}//右上角sum=0;for (int y=0; y<maxY/2; y++) {for (int x=maxX/2; x<maxX; x++) {sum+=*(pRealData3+pit3*(y)+(x)*bitCount3);}}avg=(int)(sum/(maxY/2*(maxX/2)));for (int y=0; y<maxY/2; y++) {for (int x=maxX/2; x<maxX; x++) {temp=*(pRealData3+pit3*(y)+(x)*bitCount3);if(temp>avg)temp=255;elsetemp=0;*(pRealData2+pit2*(y)+(x)*bitCount2)=temp;*(pRealData2+pit2*(y)+(x)*bitCount2+1)=temp;*(pRealData2+pit2*(y)+(x)*bitCount2+2)=temp;}}//左下角sum=0;for (int y=maxY/2; y<maxY; y++) {for (int x=0; x<maxX/2; x++) {sum+=*(pRealData3+pit3*(y)+(x)*bitCount3);}}avg=(int)(sum/(maxY/2*(maxX/2)));for (int y=maxY/2; y<maxY; y++) {for (int x=0; x<maxX/2; x++) {temp=*(pRealData3+pit3*(y)+(x)*bitCount3);if(temp>avg)temp=255;elsetemp=0;*(pRealData2+pit2*(y)+(x)*bitCount2)=temp;*(pRealData2+pit2*(y)+(x)*bitCount2+1)=temp;*(pRealData2+pit2*(y)+(x)*bitCount2+2)=temp;}}//右下角sum=0;for (int y=maxY/2; y<maxY; y++) {for (int x=maxX/2; x<maxX; x++) {sum+=*(pRealData3+pit3*(y)+(x)*bitCount3);}}avg=(int)(sum/(maxY/2*(maxX/2)));for (int y=maxY/2; y<maxY; y++) {for (int x=maxX/2; x<maxX; x++) {temp=*(pRealData3+pit3*(y)+(x)*bitCount3);if(temp>avg)temp=255;elsetemp=0;*(pRealData2+pit2*(y)+(x)*bitCount2)=temp;*(pRealData2+pit2*(y)+(x)*bitCount2+1)=temp;*(pRealData2+pit2*(y)+(x)*bitCount2+2)=temp;}}Invalidate();}