指定光照环境色卡颜色值提取源码

主要对每个色块颜色平均值提取后存储到文件,用彩色阈值分割的方法先进行逐个色块的分割,再进行平均值提取,本算法还可以优化,算法时间还可缩短。

主要代码如下:

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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章