PageRenderTime 594ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/OpenCVImage.cpp

https://gitlab.com/jimador/Online_Adaptive_Multi-Object_Tracking
C++ | 261 lines | 214 code | 17 blank | 30 comment | 23 complexity | ff86abf93988e934f617caa3e3eb8130 MD5 | raw file
  1. #include "OpenCVImage.h"
  2. using namespace cv;
  3. /*Integration of image reading process*/
  4. void ReadJPGImage(const char *fname,RgbImage *&rgbImage,int paddedX,int paddedY,unsigned char *&img,int &ncols,int &nrows)
  5. {
  6. //We use the information computed in gaussian border for padding the image border
  7. ReadColorImage(fname,rgbImage,paddedX,paddedY);
  8. IplImage *image=rgbImage->getIplImage();
  9. ncols=image->width;
  10. nrows=image->height;
  11. if(img==NULL)//have not allocated memory space for img
  12. {
  13. img=(unsigned char*)malloc(sizeof(unsigned char)*ncols*nrows);
  14. }
  15. ConvertToUnChar(rgbImage,img);
  16. }
  17. /*Read a color image from a file and may allocate space for object*/
  18. void ReadColorImage(const char *fname,RgbImage *&rgbImage,int paddedX,int paddedY)
  19. {
  20. IplImage *image,*image_b;
  21. image=cvLoadImage(fname);
  22. if(image==NULL)
  23. {
  24. fprintf(stderr,"Cannot load image %s\n",fname);
  25. assert(image!=NULL);
  26. }
  27. image_b=cvCreateImage(cvSize(image->width+paddedX*2,image->height+paddedY*2),image->depth,image->nChannels);//the padded image
  28. CvPoint offset=cvPoint(paddedX,paddedY);
  29. cvCopyMakeBorder(image,image_b, offset, IPL_BORDER_REPLICATE, cvScalarAll(0));
  30. if(rgbImage==NULL)//We should allocate space for it
  31. rgbImage=new RgbImage(image_b);//Note how we allocate space (pass by value)
  32. else
  33. *rgbImage=image_b;
  34. cvReleaseImage(&image);//Release the original image
  35. }
  36. /*Write the modified image to the file with the specific file name*/
  37. void WriteColorImage(const char *fname,const RgbImage *rgbImage)
  38. {
  39. assert(rgbImage!=NULL&&rgbImage->getIplImage()!=NULL);
  40. IplImage *image=rgbImage->getIplImage();
  41. if(!cvSaveImage(fname,image))
  42. fprintf(stderr,"Error in saving the image %s\n",fname);
  43. }
  44. /*Free the rgbImage object and the image it has loaded*/
  45. void FreeImgObj(RgbImage *&rgbImage)
  46. {
  47. if(rgbImage!=NULL)
  48. delete rgbImage;
  49. rgbImage=NULL;
  50. }
  51. /*Convert a rgbImage into 1D unsigned char array (into gray image)*/
  52. void ConvertToUnChar(RgbImage *rgbImage,unsigned char *img)
  53. {
  54. assert(rgbImage!=NULL&&img!=NULL);
  55. IplImage *iplImg=rgbImage->getIplImage();
  56. IplImage *greyImg=cvCreateImage(cvSize(iplImg->width,iplImg->height),iplImg->depth,1);
  57. cvCvtColor(iplImg,greyImg,CV_BGR2GRAY);//Convert to greyscale image
  58. int height = greyImg->height;
  59. int width = greyImg->width;
  60. int step = greyImg->widthStep/sizeof(uchar);
  61. uchar* data = (uchar *)greyImg->imageData;
  62. for(int i=0;i<height;++i)
  63. {
  64. for(int j=0;j<width;++j)
  65. img[j+i*width]=data[i*step+j];//store the values to img
  66. }
  67. cvReleaseImage(&greyImg);
  68. }
  69. /*Draw line with color rgb*/
  70. void DrawLine(IplImage *image, int neighLen, int x0, int x1, int y0, int y1, const uchar rgb[3])
  71. {
  72. CvScalar color=CV_RGB(rgb[0],rgb[1],rgb[2]);
  73. CvPoint pt1=cvPoint(x0,y0);
  74. CvPoint pt2=cvPoint(x1,y1);
  75. cvLine(image,pt1,pt2,color,neighLen);
  76. }
  77. /*Draw a rectangle*/
  78. void DrawRectangle(cv::Mat &image, const cv::Rect &r, const uchar rgb[3])
  79. {
  80. rectangle(image, r.tl(), r.br(), cv::Scalar(rgb[2],rgb[1],rgb[0]), 4);
  81. }
  82. /*Generate image path centered at <x,y> with window_height * window_width*/
  83. RgbImage *GenerateImagePatches(const RgbImage *rgbImage,int x,int y,int window_height,int window_width)
  84. {
  85. if(rgbImage!=NULL&&rgbImage->getIplImage()!=NULL)
  86. {
  87. IplImage *patch=cvCreateImage(cvSize(window_width,window_height),IPL_DEPTH_8U,3);
  88. CvPoint2D32f center=cvPoint2D32f(x,y);//col,row
  89. cvGetRectSubPix(rgbImage->getIplImage(),patch,center);
  90. return new RgbImage(patch);
  91. }
  92. return NULL;
  93. }
  94. /*Return the histogram vetor with n_bins for an image patch centered at <x,y>,
  95. with window_width * window_height
  96. Also we compute the mean & variance for each color plane*/
  97. void ComputeHistogramPatch(const RgbImage* Patch, int n_bins,float histVector[],float mean[],float variance[])//The caller must make sure that the space for spaceVector has been allocated
  98. {
  99. assert(Patch!=NULL);
  100. IplImage *patch=Patch->getIplImage();
  101. assert(patch!=NULL&&histVector!=NULL);
  102. IplImage *plane[3];//for r,g,b color plane respectively
  103. int totalPix=patch->width*patch->height;
  104. for(int k=0;k<3;k++)
  105. {
  106. plane[k]=cvCreateImage(cvSize(patch->width,patch->height),patch->depth,1);
  107. }
  108. float range[]={0,255};
  109. float *rarray[]={range};
  110. CvHistogram *hist[3];
  111. cvCvtPixToPlane(patch,plane[0],plane[1],plane[2],NULL);
  112. //int *histVector=(int*)malloc(n_bins*3*sizeof(int));//3 color planes combined into one vector
  113. int step=plane[0]->widthStep/sizeof(uchar);
  114. for(int k=0;k<3;k++)
  115. {
  116. float sum=0,sum2=0;
  117. hist[k]=cvCreateHist(1,&n_bins,CV_HIST_ARRAY,rarray,1);
  118. cvCalcHist(plane+k,hist[k]);
  119. uchar *data=(uchar*)plane[k]->imageData;
  120. for(int i=0;i<plane[k]->height;i++)
  121. {
  122. for(int j=0;j<plane[k]->width;j++)
  123. {
  124. sum+=data[i*step+j];
  125. }
  126. }
  127. mean[k]=sum/totalPix;//calculate the mean value
  128. for(int i=0;i<plane[k]->height;i++)
  129. {
  130. for(int j=0;j<plane[k]->width;j++)
  131. {
  132. sum2+=pow(data[i*step+j]-mean[k],2);
  133. }
  134. }
  135. variance[k]=sum2/totalPix;//Calculate the variance value
  136. }
  137. /*extract the value*/
  138. for(int k=0;k<3;k++)
  139. {
  140. for(int i=0;i<n_bins;i++)
  141. {
  142. float number=cvQueryHistValue_1D(hist[k],i);
  143. histVector[i+n_bins*k]=number;
  144. //printf("number=%g\n",number);
  145. }
  146. cvReleaseImage(plane+k);//Release the resources
  147. cvReleaseHist(hist+k);
  148. }
  149. }
  150. /*Compute the Chi-square distance between two histogrames
  151. length = 3* number of bins*/
  152. float CompHistAffinity(const float histi[],const float histj[],int length)
  153. {
  154. assert(histi!=NULL&&histj!=NULL);
  155. float sum=0;
  156. for(int i=0;i<length;i++)
  157. {
  158. float avg=(histi[i]+histj[i])/2;
  159. assert(histi[i]>=0&&histj[i]>=0);
  160. float delta=pow((histi[i]-avg),2)/(avg+1);
  161. sum+=delta;
  162. }
  163. return sum;
  164. /*float sum=0;
  165. for(int i=0;i<length;i++)
  166. {
  167. float up=fabs(histi[i]-histj[i]);
  168. float down=histi[i]+histj[i]+1;
  169. sum+=up/down;
  170. }
  171. return sum;*/
  172. }
  173. /*Calculate the average intensity value (RGB/3) at (center_y,center_x)*/
  174. float GetAvgIntensityValue(const IplImage *image, size_t center_x, size_t center_y, size_t width, size_t height)
  175. {
  176. assert(image!=NULL);
  177. Mat img(image);
  178. size_t width_h=width/2;//half size
  179. size_t height_h=height/2;
  180. float sum(0);
  181. for(size_t i=center_x-width_h;i<=center_x+width_h;++i)
  182. {
  183. for(size_t j=center_y-height_h;j<=center_y+width_h;++j)
  184. {
  185. if(i>=0&&i<img.cols&&j>=0&&j<img.rows)
  186. {
  187. Vec3b value=img.at<Vec3b>(j,i);//value at jth row, ith col
  188. uchar blue=value.val[0];
  189. uchar green=value.val[1];
  190. uchar red=value.val[2];
  191. float intensity=(blue+green+red)/3.0f;
  192. sum+=intensity;
  193. }
  194. }
  195. }
  196. float avg_value = sum/(width*height);
  197. return avg_value;
  198. }
  199. /*Check whether the pixel at (ceneter_y,center_y) is considered as background pixel*/
  200. bool CheckBackGroundPixel(const float *mean_app, const IplImage *cur_image,
  201. size_t center_x, size_t center_y, size_t width, size_t height, float threshold)
  202. {
  203. float appValue = GetAvgIntensityValue(cur_image, center_x, center_y, width, height);
  204. int img_width = cur_image->width;
  205. int img_height = cur_image->height;
  206. int index = center_x + center_y*img_width;
  207. float mean_app_value = mean_app[index];
  208. if(fabs(appValue-mean_app_value)<threshold)//non-significant change
  209. {
  210. return true;//a background pixel
  211. }else//there is significant change on that position
  212. return false;//foreground pixel
  213. }
  214. /*Get overlapping percentage of two rectangles*/
  215. float GetOverLapPercentage(const cv::Rect &rect1, const cv::Rect &rect2)
  216. {
  217. Rect intersection = rect1 & rect2;
  218. int area_intersect = intersection.area();
  219. if(area_intersect==0)
  220. return 0;
  221. int area_union = rect1.area() + rect2.area() - area_intersect;
  222. float score = area_intersect/(float)(area_union);
  223. if (score<=0)
  224. {
  225. return 0;
  226. }
  227. assert(score>0);
  228. return score;
  229. }
  230. /*Get center of rectangle*/
  231. Point GetRectCenter(const Rect &rect)
  232. {
  233. return Point(rect.x+rect.width/2,rect.y+rect.height/2);
  234. }
  235. /*Average two rectangles*/
  236. cv::Rect AvgRectPair(const cv::Rect &r1, const cv::Rect &r2, float weight1, float weight2)
  237. {
  238. float center_1[] = {float(r1.x + r1.width/2.0f + 0.5f), float(r1.y + r2.height/2.0f + 0.5f)};
  239. float center_2[] = {float(r2.x + r2.width/2.0f + 0.5f), float(r2.y + r2.height/2.0f + 0.5f)};
  240. float avg_center[] = {center_1[0]*weight1 + center_2[0]*weight2, center_1[1]*weight1 + center_2[1]*weight2};
  241. float avg_scale[] = {r1.width*weight1 + r2.width*weight2, r1.height*weight1 + r2.height*weight2};
  242. cv::Rect final(int(avg_center[0] - avg_scale[0]/2 + 0.5f), int(avg_center[1] - avg_scale[1]/2 + 0.5f), int(avg_scale[0] + 0.5f), int(avg_scale[1] + 0.5f));
  243. return final;
  244. }