/Gesture_Recognition/CvvImage.cpp

https://github.com/zeruniverse/Gesture_Recognition · C++ · 259 lines · 244 code · 10 blank · 5 comment · 75 complexity · 0b1df7c6e061b7caf2566445335dc056 MD5 · raw file

  1. #include "stdafx.h"
  2. #include "CvvImage.h"
  3. //////////////////////////////////////////////////////////////////////
  4. // Construction/Destruction
  5. //////////////////////////////////////////////////////////////////////
  6. CV_INLINE RECT NormalizeRect(RECT r);
  7. CV_INLINE RECT NormalizeRect(RECT r)
  8. {
  9. int t;
  10. if (r.left > r.right)
  11. {
  12. t = r.left;
  13. r.left = r.right;
  14. r.right = t;
  15. }
  16. if (r.top > r.bottom)
  17. {
  18. t = r.top;
  19. r.top = r.bottom;
  20. r.bottom = t;
  21. }
  22. return r;
  23. }
  24. CV_INLINE CvRect RectToCvRect(RECT sr);
  25. CV_INLINE CvRect RectToCvRect(RECT sr)
  26. {
  27. sr = NormalizeRect(sr);
  28. return cvRect(sr.left, sr.top, sr.right - sr.left, sr.bottom - sr.top);
  29. }
  30. CV_INLINE RECT CvRectToRect(CvRect sr);
  31. CV_INLINE RECT CvRectToRect(CvRect sr)
  32. {
  33. RECT dr;
  34. dr.left = sr.x;
  35. dr.top = sr.y;
  36. dr.right = sr.x + sr.width;
  37. dr.bottom = sr.y + sr.height;
  38. return dr;
  39. }
  40. CV_INLINE IplROI RectToROI(RECT r);
  41. CV_INLINE IplROI RectToROI(RECT r)
  42. {
  43. IplROI roi;
  44. r = NormalizeRect(r);
  45. roi.xOffset = r.left;
  46. roi.yOffset = r.top;
  47. roi.width = r.right - r.left;
  48. roi.height = r.bottom - r.top;
  49. roi.coi = 0;
  50. return roi;
  51. }
  52. void FillBitmapInfo(BITMAPINFO* bmi, int width, int height, int bpp, int origin)
  53. {
  54. assert(bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));
  55. BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
  56. memset(bmih, 0, sizeof(*bmih));
  57. bmih->biSize = sizeof(BITMAPINFOHEADER);
  58. bmih->biWidth = width;
  59. bmih->biHeight = origin ? abs(height) : -abs(height);
  60. bmih->biPlanes = 1;
  61. bmih->biBitCount = (unsigned short)bpp;
  62. bmih->biCompression = BI_RGB;
  63. if (bpp == 8)
  64. {
  65. RGBQUAD* palette = bmi->bmiColors;
  66. int i;
  67. for (i = 0; i < 256; i++)
  68. {
  69. palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
  70. palette[i].rgbReserved = 0;
  71. }
  72. }
  73. }
  74. CvvImage::CvvImage()
  75. {
  76. m_img = 0;
  77. }
  78. void CvvImage::Destroy()
  79. {
  80. cvReleaseImage(&m_img);
  81. }
  82. CvvImage::~CvvImage()
  83. {
  84. Destroy();
  85. }
  86. bool CvvImage::Create(int w, int h, int bpp, int origin)
  87. {
  88. const unsigned max_img_size = 10000;
  89. if ((bpp != 8 && bpp != 24 && bpp != 32) ||
  90. (unsigned)w >= max_img_size || (unsigned)h >= max_img_size ||
  91. (origin != IPL_ORIGIN_TL && origin != IPL_ORIGIN_BL))
  92. {
  93. assert(0); // most probably, it is a programming error
  94. return false;
  95. }
  96. if (!m_img || Bpp() != bpp || m_img->width != w || m_img->height != h)
  97. {
  98. if (m_img && m_img->nSize == sizeof(IplImage))
  99. Destroy();
  100. /* prepare IPL header */
  101. m_img = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, bpp / 8);
  102. }
  103. if (m_img)
  104. m_img->origin = origin == 0 ? IPL_ORIGIN_TL : IPL_ORIGIN_BL;
  105. return m_img != 0;
  106. }
  107. void CvvImage::CopyOf(CvvImage& image, int desired_color)
  108. {
  109. IplImage* img = image.GetImage();
  110. if (img)
  111. {
  112. CopyOf(img, desired_color);
  113. }
  114. }
  115. #define HG_IS_IMAGE(img) \
  116. ((img) != 0 && ((const IplImage*)(img))->nSize == sizeof(IplImage) && \
  117. ((IplImage*)img)->imageData != 0)
  118. void CvvImage::CopyOf(IplImage* img, int desired_color)
  119. {
  120. if (HG_IS_IMAGE(img))
  121. {
  122. int color = desired_color;
  123. CvSize size = cvGetSize(img);
  124. if (color < 0)
  125. color = img->nChannels > 1;
  126. if (Create(size.width, size.height,
  127. (!color ? 1 : img->nChannels > 1 ? img->nChannels : 3) * 8,
  128. img->origin))
  129. {
  130. cvConvertImage(img, m_img, 0);
  131. }
  132. }
  133. }
  134. bool CvvImage::Load(const char* filename, int desired_color)
  135. {
  136. IplImage* img = cvLoadImage(filename, desired_color);
  137. if (!img)
  138. return false;
  139. CopyOf(img, desired_color);
  140. cvReleaseImage(&img);
  141. return true;
  142. }
  143. bool CvvImage::LoadRect(const char* filename,
  144. int desired_color, CvRect r)
  145. {
  146. if (r.width < 0 || r.height < 0) return false;
  147. IplImage* img = cvLoadImage(filename, desired_color);
  148. if (!img)
  149. return false;
  150. if (r.width == 0 || r.height == 0)
  151. {
  152. r.width = img->width;
  153. r.height = img->height;
  154. r.x = r.y = 0;
  155. }
  156. if (r.x > img->width || r.y > img->height ||
  157. r.x + r.width < 0 || r.y + r.height < 0)
  158. {
  159. cvReleaseImage(&img);
  160. return false;
  161. }
  162. /* truncate r to source image */
  163. if (r.x < 0)
  164. {
  165. r.width += r.x;
  166. r.x = 0;
  167. }
  168. if (r.y < 0)
  169. {
  170. r.height += r.y;
  171. r.y = 0;
  172. }
  173. if (r.x + r.width > img->width)
  174. r.width = img->width - r.x;
  175. if (r.y + r.height > img->height)
  176. r.height = img->height - r.y;
  177. cvSetImageROI(img, r);
  178. CopyOf(img, desired_color);
  179. cvReleaseImage(&img);
  180. return true;
  181. }
  182. bool CvvImage::Save(const char* filename)
  183. {
  184. if (!m_img)
  185. return false;
  186. cvSaveImage(filename, m_img);
  187. return true;
  188. }
  189. void CvvImage::Show(const char* window)
  190. {
  191. if (m_img)
  192. cvShowImage(window, m_img);
  193. }
  194. void CvvImage::Show(HDC dc, int x, int y, int w, int h, int from_x, int from_y)
  195. {
  196. if (m_img && m_img->depth == IPL_DEPTH_8U)
  197. {
  198. uchar buffer[sizeof(BITMAPINFOHEADER)+1024];
  199. BITMAPINFO* bmi = (BITMAPINFO*)buffer;
  200. int bmp_w = m_img->width, bmp_h = m_img->height;
  201. FillBitmapInfo(bmi, bmp_w, bmp_h, Bpp(), m_img->origin);
  202. from_x = MIN(MAX(from_x, 0), bmp_w - 1);
  203. from_y = MIN(MAX(from_y, 0), bmp_h - 1);
  204. int sw = MAX(MIN(bmp_w - from_x, w), 0);
  205. int sh = MAX(MIN(bmp_h - from_y, h), 0);
  206. SetDIBitsToDevice(
  207. dc, x, y, sw, sh, from_x, from_y, from_y, sh,
  208. m_img->imageData + from_y*m_img->widthStep,
  209. bmi, DIB_RGB_COLORS);
  210. }
  211. }
  212. void CvvImage::DrawToHDC(HDC hDCDst, RECT* pDstRect)
  213. {
  214. if (pDstRect && m_img && m_img->depth == IPL_DEPTH_8U && m_img->imageData)
  215. {
  216. uchar buffer[sizeof(BITMAPINFOHEADER)+1024];
  217. BITMAPINFO* bmi = (BITMAPINFO*)buffer;
  218. int bmp_w = m_img->width, bmp_h = m_img->height;
  219. CvRect roi = cvGetImageROI(m_img);
  220. CvRect dst = RectToCvRect(*pDstRect);
  221. if (roi.width == dst.width && roi.height == dst.height)
  222. {
  223. Show(hDCDst, dst.x, dst.y, dst.width, dst.height, roi.x, roi.y);
  224. return;
  225. }
  226. if (roi.width > dst.width)
  227. {
  228. SetStretchBltMode(
  229. hDCDst, // handle to device context
  230. HALFTONE);
  231. }
  232. else
  233. {
  234. SetStretchBltMode(
  235. hDCDst, // handle to device context
  236. COLORONCOLOR);
  237. }
  238. FillBitmapInfo(bmi, bmp_w, bmp_h, Bpp(), m_img->origin);
  239. ::StretchDIBits(
  240. hDCDst,
  241. dst.x, dst.y, dst.width, dst.height,
  242. roi.x, roi.y, roi.width, roi.height,
  243. m_img->imageData, bmi, DIB_RGB_COLORS, SRCCOPY);
  244. }
  245. }
  246. void CvvImage::Fill(int color)
  247. {
  248. cvSet(m_img, cvScalar(color & 255, (color >> 8) & 255, (color >> 16) & 255, (color >> 24) & 255));
  249. }