3 #include "core\core.hpp"
8 CCell::CCell(
void) : m_img(Mat()), m_imgSize(cvSize(0, 0)), m_LUT(Mat()), m_R(-1.0), m_r(-1.0), m_nCells(-1), m_cellIntApp(
CELL_AVG), m_cellData(Mat())
13 CCell::CCell(CvSize imgSize,
cell_int_app cellIntApp) : m_img(Mat()), m_imgSize(imgSize), m_LUT(Mat()), m_R(-1.0), m_r(-1.0), m_nCells(-1), m_cellIntApp(cellIntApp), m_cellData(Mat())
18 CCell::CCell(Mat &img,
cell_int_app cellIntApp) : m_LUT(Mat()), m_R(-1.0), m_r(-1.0), m_nCells(-1), m_cellIntApp(cellIntApp), m_cellData(Mat())
21 m_imgSize = img.size();
25 CCell::CCell(
double R) : m_img(Mat()), m_imgSize(cvSize(0, 0)), m_LUT(Mat()), m_R(R), m_r(0.5*sqrt(3.0)*R), m_nCells(-1), m_cellIntApp(
CELL_AVG), m_cellData(Mat())
30 CCell::CCell(CvSize imgSize,
double R,
cell_int_app cellIntApp) : m_img(Mat()), m_imgSize(imgSize), m_LUT(Mat()), m_R(R), m_r(0.5*sqrt(3.0)*R), m_nCells(-1), m_cellIntApp(cellIntApp), m_cellData(Mat())
35 CCell::CCell(Mat &img,
double R,
cell_int_app cellIntApp) : m_LUT(Mat()), m_R(R), m_r(0.5*sqrt(3.0)*R), m_nCells(-1), m_cellIntApp(cellIntApp), m_cellData(Mat())
38 m_imgSize = img.size();
44 if (!m_img.empty()) m_img.release();
45 if (!m_LUT.empty()) m_LUT.release();
46 if (!m_cellData.empty()) m_cellData.release();
51 if (!m_img.empty()) m_img.release();
52 m_imgSize = cvSize(0, 0);
53 if (!m_LUT.empty()) m_LUT.release();
57 if (!m_cellData.empty()) m_cellData.release();
63 HCELL_ASSERT_MSG(!img.empty(),
"The image is not set");
65 if (!m_img.empty()) m_img.release();
68 if ((m_imgSize.width != img.size().width) || (m_imgSize.height != img.size().height)) {
69 if (!m_LUT.empty()) m_LUT.release();
72 m_imgSize = img.size();
73 if (!m_cellData.empty()) m_cellData.release();
79 HCELL_ASSERT_MSG(R >= MIN_RADIUS,
"The cell radius is not set or has a wrong value");
82 if (!m_LUT.empty()) m_LUT.release();
84 m_r = 0.5 * sqrt(3.0) * R;
86 if (!m_cellData.empty()) m_cellData.release();
91 m_cellIntApp = cellIntApp;
92 if (!m_cellData.empty()) m_cellData.release();
101 if (res.
S >= 0) res.
S *= 3 * m_r;
102 if (m_nCells < 0) calculate_nCells();
109 return d2idx(cvPoint2D64f(x, y));
114 if (m_nCells < 0) calculate_nCells();
116 double dx = 2.0 * m_r;
117 double imgWidth =
static_cast<double>(m_imgSize.width);
118 int width0 =
static_cast<int> (0.99 + imgWidth / dx);
119 int width1 = 1 +
static_cast<int> (0.99 + (imgWidth - m_r) / dx);
121 Point c = idx2h(idx, m_R, m_imgSize);
124 if ((c.y % 2) == 0) d = 1;
128 case 0: c.x += 1;
break;
129 case 1: c.x += d; c.y += 1;
break;
130 case 2: c.x += d - 1; c.y += 1;
break;
131 case 3: c.x -= 1;
break;
132 case 4: c.x += d - 1; c.y -= 1;
break;
133 case 5: c.x += d; c.y -= 1;
break;
134 default: res = -1;
break;
136 if ((c.x < 0) || (c.y < 0)) res = -1;
137 if (((c.y % 2) == 0) && (c.x >= width0)) res = -1;
138 if (((c.y % 2) != 0) && (c.x >= width1)) res = -1;
141 if (res >= m_nCells) res = -1;
148 int *res =
new int[6];
155 if (m_cellData.empty()) calculate_cellData();
159 int C = m_img.channels();
160 for (
int c = 0; c < C; c++) res.val[c] = m_cellData.at<
double>(0, C * idx + c);
169 r1 = (a.x - x.x) * (b.y - a.y) - (b.x - a.x) * (a.y - x.y);
170 r2 = (b.x - x.x) * (c.y - b.y) - (c.x - b.x) * (b.y - x.y);
171 r3 = (c.x - x.x) * (a.y - c.y) - (a.x - c.x) * (c.y - x.y);
172 if (SIGN(r1) == SIGN(r2) == SIGN(r3))
return true;
177 int CCell::calculate_LUT(
void)
180 HCELL_ASSERT_MSG((m_imgSize.height != 0) && (m_imgSize.width != 0),
"The image size is not set");
182 if (!m_LUT.empty()) m_LUT.release();
183 m_LUT.create(m_imgSize, CV_32SC1);
185 double dx = 2.0 * m_r;
186 double dy = 1.5 * m_R;
188 for (
register int y = 0; y < m_LUT.rows; y++) {
189 dword *pLUT = m_LUT.ptr<dword>(y);
190 for (
register int x = 0; x < m_LUT.cols; x++) {
191 CvPoint2D64f X = cvPoint2D64f(x, y);
196 C.y = c.y * dy + 0.5 * m_R;
197 C.x = c.x * dx + m_r;
199 if ((c.y % 2) == 1) X.x += m_r;
200 bool inside = ifInsideCell(X, C);
202 if ((c.y % 2) == 0) {
203 if (X.x >= C.x) c.x++;
206 if (X.x < C.x) c.x--;
216 int CCell::calculate_nCells(
void)
219 HCELL_ASSERT_MSG(((m_R >= 0) && (m_r >= 0)),
"The cell radius is not set or has a wrong value");
222 if (m_LUT.empty())
if ((res = calculate_LUT()) < 0)
return res;
225 minMaxLoc(m_LUT, NULL, &maxVal, NULL, NULL);
226 m_nCells =
static_cast<int>(maxVal) + 1;
231 int CCell::calculate_cellData(
void)
234 HCELL_ASSERT_MSG(!m_img.empty(),
"The image is not set");
236 int C = m_img.channels();
238 if (m_nCells < 0) calculate_nCells();
239 if (m_cellData.empty()) {
240 m_cellData.create(1, m_nCells, CV_MAKE_TYPE(CV_64F, C));
244 double * pData = m_cellData.ptr<
double>(0);
245 int * pNumVal = NULL;
246 int * pMaxVal = NULL;
249 if (m_cellIntApp ==
CELL_MV) len *= 256;
250 pNumVal =
new int[len];
251 if (m_cellIntApp ==
CELL_MV) pMaxVal =
new int[m_nCells];
253 for (
int c = 0; c < C; c++) {
254 memset(pNumVal, 0, len *
sizeof(
int));
255 if (pMaxVal != NULL) memset(pMaxVal, 0, m_nCells *
sizeof(
int));
256 for (
register int y = 0; y < m_img.rows; y++) {
257 byte *pImg = m_img.ptr<byte>(y);
258 for (
register int x = 0; x < m_img.cols; x++) {
259 int id = d2idx(cvPoint2D64f(x, y));
260 byte val = pImg[C*x + c];
262 if (pMaxVal != NULL) {
263 pNumVal[256 *
id + val]++;
264 if (pNumVal[256 *
id + val] > pMaxVal[
id]) {
266 pData[C*
id + c] = val;
270 pData[C*
id + c] = (pNumVal[id] * pData[C*
id + c] + val) / (pNumVal[
id] + 1);
280 if (pMaxVal != NULL)
delete[] pMaxVal;
285 bool CCell::ifInsideCell(CvPoint2D64f x, CvPoint2D64f C)
const
288 for (
int i = 0; i < 6; i++) {
290 res =
ifInsideTriangle(x, C, getBoundaryPoint(C, i, m_R), getBoundaryPoint(C, j, m_R));
296 CvPoint2D64f CCell::getBoundaryPoint(CvPoint2D64f C,
int i,
double R)
298 double r = 0.5 * sqrt(3.0) * R;
300 case 0:
return cvPoint2D64f(C.x, C.y - R);
301 case 1:
return cvPoint2D64f(C.x + r, C.y - 0.5*R);
302 case 2:
return cvPoint2D64f(C.x + r, C.y + 0.5*R);
303 case 3:
return cvPoint2D64f(C.x, C.y + R);
304 case 4:
return cvPoint2D64f(C.x - r, C.y + 0.5*R);
305 case 5:
return cvPoint2D64f(C.x - r, C.y - 0.5*R);
306 default:
return cvPoint2D64f(0, 0);
310 Point CCell::idx2h(
int idx,
double R, CvSize imgSize)
312 double r = 0.5 * sqrt(3.0) * R;
314 double imgWidth =
static_cast<double>(imgSize.width);
315 int width0 =
static_cast<int> (0.99 + imgWidth / dx);
316 int width1 = 1 +
static_cast<int> (0.99 + (imgWidth - r) / dx);
317 int widthD = width0 + width1;
321 res.y = idx / widthD;
322 res.x = idx - res.y * widthD;
324 if (res.x >= width0) {
331 int CCell::h2idx(Point c)
const
333 double dx = 2.0 * m_r;
334 double imgWidth =
static_cast<double>(m_imgSize.width);
335 int width0 =
static_cast<int> (0.99 + imgWidth / dx);
336 int width1 = 1 +
static_cast<int> (0.99 + (imgWidth - m_r) / dx);
337 int widthD = width0 + width1;
344 if (b == 1) res += width0;
350 CvPoint2D64f CCell::idx2d(
int idx,
double R, CvSize imgSize)
352 double r = 0.5 * sqrt(3.0) * R;
357 Point C = idx2h(idx, R, imgSize);
361 res.y = C.y * dy + 0.5 * R;
362 res.x = C.x * dx + r;
363 if ((C.y % 2) != 0) res.x -= r;
368 int CCell::d2idx(CvPoint2D64f C) {
369 if (m_LUT.empty()) {
if (calculate_LUT() != 0)
return -1; }
370 return m_LUT.at<
int>(
static_cast<int>(C.y), static_cast<int>(C.x));
373 Point CCell::d2h(CvPoint2D64f C)
const
375 double dx = 2.0 * m_r;
376 double dy = 1.5 * m_R;
379 c.y =
static_cast<int>((C.y + 0.5 * m_R) / dy);
380 c.x =
static_cast<int>(C.x / dx);
int N
Number of hexagons in the image.
int getNeighbourIDX(int idx, int i)
Returns the neighbouring cell index.
cell_int_app
Cell interpolation approach.
void setRadius(double R)
(Re-) sets the hexagon outer radius
CvScalar getVal(int idx)
Returns the color of the specified cell.
double r
Hexagon inner radius.
void setInterpolationApproach(cell_int_app cellIntApp)
(Re-) sets the interpolation approach for cell color generation
double R
Hexagon outer radius.
bool ifInsideTriangle(CvPoint2D64f x, CvPoint2D64f a, CvPoint2D64f b, CvPoint2D64f c)
int * getNeighbourhood(int idx)
Returns all 6 neighbouring cell indexs.
int getIDX(int x, int y)
Returns the cell index.
cell_params getInfo(void)
Returns the cell parameters.
double S
Hexagon area in pixels.
Majority voting approach.
void setImage(Mat &img)
(Re-) sets the image
CCell(void)
Default constuctor.
Cell parameters structure.
void clear(void)
Resets the class by releasing memory and setting the class variable by default.