官术网_书友最值得收藏!

4.4.1 圖像的標識及特征提取

編程實現

[1] 在Demo1中創建類CCluster以實現模糊聚類的相應功能,在其中添加函數GetFeature(),進行有關圖像的標識和特征提取。具體實現代碼如代碼4-1所示。

代碼4-1 GetFeature()函數

        void CCluster::GetFeature()
        {
            ////////////////////以下對數據區域標號whx/////////////////////
            BYTE * p_temp;
            int stop;
            int i,j;
            int counter;//記錄相互獨立的連通區域的個數
            int present;//記錄當前點的值1,2,...,counter
            stop=0;
            counter=0;
            p_temp=new BYTE[wide*height];//開辟一個臨時內存區×××××
            memset(p_temp,255,wide*height);//置白
            //從左到右、從上到下標號
            const int T=5;//T為閾值,RGB值小于該閾值被認為是黑
            for(i=0; i<wide; i++)//將第零行置白
                *(m_pData+(height-1)*wide+i)=255;
            for(j=0;j<height;j++)//將第零列置白
                *(m_pData+(height-j-1)*wide)=255;
            for( j=1;j<height-1;j++) // 從第一行開始搜索
            {
                if(stop==1)//判斷連通區是否太多
                    break;
                for( i=1;i<wide-1;i++)   // 從第一列開始搜索
                {
                    if(counter>255)
                    {
                          AfxMessageBox("連通區數目太多,請減少樣品個數");
                          stop=1;
                          return;
                    }
                    if(*(m_pData+(height-j-1)*wide+i)<T)//若當前點為黑點
                    {
                          if(*(m_pData+(height-j-1+1)*wide+i+1)<T)//若當前點的右上點為黑點
                          {
                              *(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)
                                    *wide+i+1);
                              //當前點標號應該與右上點相同
                              present=*(p_temp+(height-j-1+1)*wide+i+1);//記錄當前點的標號
                            if(*(m_pData+(height-j-1)*wide+i-1)<T && *(p_temp+
    (height-j-1)*wide+i-1)!=present)//左前與右上點都為黑且標號不同
                            {
                                int temp=*(p_temp+(height-j-1)*wide+i-1);//記錄左前點的標號
                                if (present>temp)//當前點標號記錄兩者中的較小值
                                {
                                    present=temp;
                                    temp=*(p_temp+(height-j-1+1)*wide+i+1);
                                }
                                counter--;//合并左前和右上標號,標號總數減一
                                for(int m=1;m<=height-1;m++)
                                    for(int n=1;n<=wide-1;n++)
                                    {
                                        if(*(p_temp+(height-m-1)*wide+n)==temp)
                                        //將較大標號改成較小標號
                                        {
                                              *(p_temp+(height-m-1)*wide+n)=present;
                                        }
                                        else if (*(p_temp+(height-m-1)*wide+n)>temp)
                                        //將較大標號以后的所有標號減一,以保持標號的連續性
                                        {
*(p_temp+(height-m-1)*wide+n)-=1;
                                        }
                                    }
                            }
                            if( *(m_pData+(height-j-1+1)*wide+i-1)<T && *(p_temp+
    (height-j-1+1)*wide+i-1)!=present)//左上與右上點都為黑且標號不同
                            {
                                counter--;//合并左上和右上標號,標號總數減一
                                int temp=*(p_temp+(height-j-1+1)*wide+i-1);//記錄左上點的值
                                if (present<temp)//當前點標號記錄兩者中的較小值
                                {
                                    temp=present;
                                    present=*(p_temp+(height-j-1+1)*wide+i-1);
                                }
                                for(int m=1;m<=height-1;m++)
                                    for(int n=1;n<=wide-1;n++)
                                    {
                                        if(*(p_temp+(height-m-1)*wide+n)==present)
                                        //將較大標號改成較小標號
                                        {
                                              *(p_temp+(height-m-1)*wide+n)=temp;
                                        }
                                        else if (*(p_temp+(height-m-1)*wide+n)>present)
                                        //將較大標號以后的所有標號減一,以保持標號的連續性
                                        {
                                              *(p_temp+(height-m-1)*wide+n)-=1;
                                          }
                                      }
                                  present=temp;
                            }
                        }
                    else if(*(m_pData+(height-j-1+1)*wide+i)<T)
                                                          //當前點黑,右上不為黑,正上為黑
                        {
                            *(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)
                                  *wide+i);
                                          //當前標號=正上標號
                            present=*(p_temp+(height-j-1+1)*wide+i);
                        }
                        else if(*(m_pData+(height-j-1+1)*wide+i-1)<T)//左上
                        {
                            *(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)
    *wide+i-1);
                            present=*(p_temp+(height-j-1+1)*wide+i-1);}
                        else if(*(m_pData+(height-j-1)*wide+i-1)<T)//左前
                        {
                            *(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1)
    *wide+i-1);
                            present=*(p_temp+(height-j-1)*wide+i-1);
                        }
                        else//產生新標號
                        {
                            ++counter;
                            present=counter;
                            *(p_temp+(height-j-1)*wide+i)=present;
                        }
                    }//end if
                }// 列
            }//end行
        // //////////////////////以上對數據區域標號//////////////////////////
        //////////////////////以下獲得各個樣品所在位置及編號///////////////////
            patternnum=counter;//樣品總數
            if (m_pattern!=NULL)
                delete []m_pattern;
            m_pattern=new Pattern[patternnum];
            for( i=0;i<patternnum;i++)
            {
                m_pattern[i].index=i+1;
                m_pattern[i].category=0;
                m_pattern[i].lefttop.x=wide;
                m_pattern[i].lefttop.y=height;
                m_pattern[i].rightbottom.x=0;
                m_pattern[i].rightbottom.y=0;
            }
            for(int t=1;t<=patternnum;t++)//記錄每個樣品(獨立連通區域)的左上、右下點坐標
            {
                for(int j=1;j<height-1;j++)//搜索整幅圖像
                    for(int i=1;i<wide-1;i++)
                    {
                        if(*(p_temp+(height-j-1)*wide+i)==t)
                        {
                            if (m_pattern[t-1].lefttop.x>i)//get the lefttop point
                                  m_pattern[t-1].lefttop.x=i;
                            if (m_pattern[t-1].lefttop.y>j)
                                  m_pattern[t-1].lefttop.y=j;
                            if (m_pattern[t-1].rightbottom.x<i)//get the rightbottom point
                                  m_pattern[t-1].rightbottom.x=i;
                            if (m_pattern[t-1].rightbottom.y<j)
                                  m_pattern[t-1].rightbottom.y=j;
                        }
                    }
            }
            delete []p_temp;
            //////////////////////以下獲得所有樣品特征放入m_pattern中////////////////////
            for ( i=0;i<patternnum;i++)//=patternnum
            {
                CalFeature(&m_pattern[i]);//調用函數計算第i號模板的值
            }
            //////////////////////以上獲得所有樣品特征放入m_pattern中////////////////////
        }

[2] 上述代碼中,CalFeature ()函數用于計算樣品的特征值,該函數的實現代碼如代碼4-2所示。

代碼4-2 CalFeature ()函數

        void CCluster::CalFeature(CCluster::Pattern *m_pattern)
        {
            int w,h,count;
            int i,j;
            w=(int)(m_pattern->rightbottom.x-m_pattern->lefttop.x)/N;//特征值中每個特征的寬
            h=(int)(m_pattern->rightbottom.y-m_pattern->lefttop.y)/N;//特征值中每個特征的高
            for ( j=0;j<N;j++)
            {
                for ( i=0;i<N;i++)
                {
                    count=0;//每個特征內黑點的個數
                    for(int m= height-m_pattern->rightbottom.y+h*j;m<height-m_pattern->
                          rightbottom.y+h*j+h;m++)
                        for (int n=m_pattern->lefttop.x+i*w; n<m_pattern->lefttop.x+i*w
                              +w; n++)
                              if (*(m_pData+m*wide+n)==0)
                                  count++;
                    m_pattern->feature[j*N+i]=(double)count/(double)(w*h);
                }
            }
        }
主站蜘蛛池模板: 玉溪市| 南涧| 瑞丽市| 洞头县| 望谟县| 资阳市| 墨竹工卡县| 西藏| 罗甸县| 宁强县| 中超| 中牟县| 台江县| 洛浦县| 五华县| 钟山县| 湟源县| 易门县| 平凉市| 平江县| 融水| 华宁县| 哈尔滨市| 汪清县| 奉新县| 大田县| 平利县| 湘阴县| 改则县| 张家港市| 贵南县| 康平县| 中牟县| 江永县| 德江县| 饶平县| 钟山县| 雅江县| 准格尔旗| 沾化县| 即墨市|