指定光照環境色卡顏色值提取源碼

主要對每個色塊顏色平均值提取後存儲到文件,用彩色閾值分割的方法先進行逐個色塊的分割,再進行平均值提取,本算法還可以優化,算法時間還可縮短。

主要代碼如下:

void HuiDuTongJi(IplImage* img,int *pArray)
//圖像的灰度統計
{

    if(img->nChannels != 1)

    {
        cout<<"It's not a SigleChannelPic!"<<endl;
        return;
    }  

    

    //=====================循環變量====================//

    int i,j;

    //=====================輸入圖像信息====================//

    int imgWidth = img->width;          

    int imgHeight = img->height;        

    int imgDepth = img->depth;          

    int imgChannels = img->nChannels;           

    int imgSize = img->imageSize;           

    int imgStep = img->widthStep/sizeof(uchar);

    uchar* imgData  = (uchar *)img->imageData;  

    int imgLen = imgWidth*imgHeight;                //

     

    //統計灰度級

    for(i = 0 ; i< imgHeight ; i++)
    {
        for(j = 0; j< imgWidth ; j++)
        {

            pArray[imgData[i*imgStep+j*imgChannels]]++;

        }

    }

}

void HistThreshold(IplImage* img, double m_lowerLimit, double m_upperLimit)
//灰度直方圖閾值分割
{

    //=====================循環變量====================//

    int i,j,k;

    //=====================輸入圖像信息====================//

    int imgWidth = img->width;          

    int imgHeight = img->height;        

    int imgDepth = img->depth;          

    int imgChannels = img->nChannels;           

    int imgSize = img->imageSize;           

    int imgStep = img->widthStep/sizeof(uchar);

    uchar* imgData  = (uchar *)img->imageData;  

    int imgLen = imgWidth*imgHeight;         

 

    IplImage* dst = cvCreateImage(cvGetSize(img),img->depth,img->nChannels);

 

    for(i = 0 ;i < imgHeight; i++)
    {

        for(j =0 ; j <imgWidth ; j++)
        {

            for(k = 0; k<imgChannels;k++)
            {
                //當灰度值不在範圍之內時灰度值付爲0,否則爲255

                if( imgData[i*imgStep+j*imgChannels+k] <m_lowerLimit || imgData[i*imgStep+j*imgChannels+k] > m_upperLimit)
                {

                    (((uchar *)(dst->imageData))[i*imgStep+j*imgChannels+k]) = 255;             

                }
                else
                {

                    (((uchar *)(dst->imageData))[i*imgStep+j*imgChannels+k]) = 0;

                }

            }

        }  

    }
 cvCopy(dst,img,0);
    cvReleaseImage(&dst);

}

/*直方圖方法分割彩色圖像 */
void HistSegment(IplImage* img,double lowerLimit, double upperLimit)
{

    if(img->nChannels != 1)
    {
        cout<<"It's not a SigleChannelPic!"<<endl;
        return;
    }

 

    //=====================輸入圖像信息====================//

    int imgWidth = img->width;              

    int imgHeight = img->height;            

    int imgDepth = img->depth;              

    int imgChannels = img->nChannels;           

    int imgSize = img->imageSize;               

    int imgStep = img->widthStep/sizeof(uchar);

    uchar* imgData  = (uchar *)img->imageData;  

    int imgLen = imgWidth*imgHeight;           

 

    //保存像素範圍
    double m_lowerLimit,m_upperLimit;

    //指向灰度級的數據指針

    int *pArray;

    //分配內存

    pArray = new int[256];

    //初始化內存
    for(int i =0 ;i <256 ;i++)

    {
        pArray[i] = 0;

    }

 

    //總的象素個數
    int   Total;

    Total = imgWidth *  imgHeight ;

 

    //調用函數獲得每一級灰度級的值

   // HuiDuTongJi(img,pArray);

 

    m_lowerLimit  = lowerLimit;

    m_upperLimit =  upperLimit;

        //閾值分割
    HistThreshold(img,m_lowerLimit,m_upperLimit);

    

    delete []pArray;

}

int picSegProcess::seKaSegment(IplImage *pSrcImage,CvScalar lowerLimit, CvScalar upperLimit, CvScalar *resultColor,CvRect *rectParam)
{
 //  定義工作位圖

    IplImage* src=pSrcImage;

    IplImage* imgR = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
    IplImage* imgG = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
 IplImage* imgB = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
 IplImage* imgResult = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);

    //  源圖像信息

    int width = src->width;

    int height = src->height;

    int channel = src->nChannels;

    
    int i,j;
    double R,G,B;//,H,S,V;
 int sumR=0,sumG=0,sumB=0;
 int RGBnum=0;

    for(j=0;j<height;j++)
    {
        for(i=0;i<width;i++)
        {
            B = ((uchar*)(src->imageData + j*src->widthStep))[i*channel];

            G = ((uchar*)(src->imageData + j*src->widthStep))[i*channel+1];

            R = ((uchar*)(src->imageData + j*src->widthStep))[i*channel+2];

   

            ((uchar*)(imgR->imageData + j*imgR->widthStep))[i*imgR->nChannels] = (uchar)R;

            ((uchar*)(imgG->imageData + j*imgG->widthStep))[i*imgG->nChannels] = (uchar)G;

   ((uchar*)(imgB->imageData + j*imgB->widthStep))[i*imgB->nChannels] = (uchar)B;

        }

    }

static void testSekaSeg()
{
 IplImage *pRoiImage =NULL; 
 IplImage *tempResult =NULL;
 char pic_path[MAX_PATH]={0};
 char tempS[MAX_PATH]={0};
 char buf[256]={0};
 picSegProcess mytest;


 GetCurrentDirectory(MAX_PATH,pic_path);
 sprintf(tempS, "%s%s", pic_path,"\\pic\\mytest1.jpg");
 pRoiImage = cvLoadImage(tempS, CV_LOAD_IMAGE_UNCHANGED);
 
 int rectW = 6;//橫向色塊數
 int rectH = 4;//縱向色塊數
 int segParam=5;//RGB顏色判斷範圍
 int tempHeigh=pRoiImage->height/rectH;
 int tempWidth=pRoiImage->width/rectW;
 int HRemainder=pRoiImage->height%rectH;
 int WRemainder=pRoiImage->width%rectW;
 int h=0;
 int w=0;
 int tempNum=0;
 CvScalar tempColor;
 CvScalar avrColor;
 CvRect rectParam;
 FILE* tempFd=NULL;
 IplImage *tempDest= cvCreateImage(cvGetSize(pRoiImage), pRoiImage->depth, pRoiImage->nChannels);
 sprintf(tempS, "%s%s", pic_path,"\\avrResult.txt");
 
 for (h=0;h<pRoiImage->height-HRemainder;h+=tempHeigh)
 {
  for (w=0;w<pRoiImage->width-WRemainder;w+=tempWidth)
  {
   /*CvPoint pt1;
   pt1.x=w;
   pt1.y=h;
   CvPoint pt2;
   pt2.x=w+tempWidth;
   pt2.y=h+tempHeigh;
   cvRectangle(pRoiImage,pt1,pt2,Scalar(0,255,0));*/
   cvCopy(pRoiImage,tempDest,0);

   tempColor.val[0] = ((uchar*)(tempDest->imageData + (h+tempHeigh/2)*tempDest->widthStep))[(w+tempWidth/2)*tempDest->nChannels];
            tempColor.val[1] = ((uchar*)(tempDest->imageData + (h+tempHeigh/2)*tempDest->widthStep))[(w+tempWidth/2)*tempDest->nChannels+1];
            tempColor.val[2] = ((uchar*)(tempDest->imageData + (h+tempHeigh/2)*tempDest->widthStep))[(w+tempWidth/2)*tempDest->nChannels+2];

   CvScalar LColor = cvScalar(tempColor.val[0]-segParam,tempColor.val[1]-segParam,tempColor.val[2]-segParam);
   CvScalar UpColor = cvScalar(tempColor.val[0]+segParam,tempColor.val[1]+segParam,tempColor.val[2]+segParam);
   rectParam.x=w;
   rectParam.y=h;
   rectParam.height=tempHeigh;
   rectParam.width=tempWidth;
   mytest.seKaSegment(tempDest,LColor,UpColor,&avrColor,&rectParam);
   tempNum++;
   if((tempFd = fopen(tempS,"a+"))==NULL){ 
    if(NULL != tempS)
     printf("can not open file %s\n",tempS);
    else
     printf("can not open file,file path is NULL\n");
    return;
   }
   sprintf(buf,"%d,B:%f,G:%f,R:%f\n",tempNum, avrColor.val[0],avrColor.val[1],avrColor.val[2]);
   fwrite(buf,strlen(buf)+1,1,tempFd);
   fclose(tempFd);
  }
 }


 /*sprintf(tempS, "%s%s", pic_path,"\\picResult\\testSekaSeg.jpg");
 cvSaveImage( tempS, pRoiImage,0);*/

 cvReleaseImage(&tempDest);
 cvReleaseImage(&pRoiImage);
}

原圖像

色塊分割實例圖像


發佈了47 篇原創文章 · 獲贊 64 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章