93 0, 1048576, 524288, 349525, 262144, 209715, 174762, 149796,
94 131072, 116508, 104857, 95325, 87381, 80659, 74898, 69905,
95 65536, 61680, 58254, 55188, 52428, 49932, 47662, 45590,
96 43690, 41943, 40329, 38836, 37449, 36157, 34952, 33825,
97 32768, 31775, 30840, 29959, 29127, 28339, 27594, 26886,
98 26214, 25575, 24966, 24385, 23831, 23301, 22795, 22310,
99 21845, 21399, 20971, 20560, 20164, 19784, 19418, 19065,
100 18724, 18396, 18078, 17772, 17476, 17189, 16912, 16644,
101 16384, 16131, 15887, 15650, 15420, 15196, 14979, 14768,
102 14563, 14364, 14169, 13981, 13797, 13617, 13443, 13273,
103 13107, 12945, 12787, 12633, 12483, 12336, 12192, 12052,
104 11915, 11781, 11650, 11522, 11397, 11275, 11155, 11037,
105 10922, 10810, 10699, 10591, 10485, 10381, 10280, 10180,
106 10082, 9986, 9892, 9799, 9709, 9619, 9532, 9446,
107 9362, 9279, 9198, 9118, 9039, 8962, 8886, 8811,
108 8738, 8665, 8594, 8525, 8456, 8388, 8322, 8256,
109 8192, 8128, 8065, 8004, 7943, 7884, 7825, 7767,
110 7710, 7653, 7598, 7543, 7489, 7436, 7384, 7332,
111 7281, 7231, 7182, 7133, 7084, 7037, 6990, 6944,
112 6898, 6853, 6808, 6765, 6721, 6678, 6636, 6594,
113 6553, 6512, 6472, 6432, 6393, 6355, 6316, 6278,
114 6241, 6204, 6168, 6132, 6096, 6061, 6026, 5991,
115 5957, 5924, 5890, 5857, 5825, 5793, 5761, 5729,
116 5698, 5667, 5637, 5607, 5577, 5548, 5518, 5489,
117 5461, 5433, 5405, 5377, 5349, 5322, 5295, 5269,
118 5242, 5216, 5190, 5165, 5140, 5115, 5090, 5065,
119 5041, 5017, 4993, 4969, 4946, 4922, 4899, 4877,
120 4854, 4832, 4809, 4788, 4766, 4744, 4723, 4702,
121 4681, 4660, 4639, 4619, 4599, 4578, 4559, 4539,
122 4519, 4500, 4481, 4462, 4443, 4424, 4405, 4387,
123 4369, 4350, 4332, 4315, 4297, 4279, 4262, 4245,
124 4228, 4211, 4194, 4177, 4161, 4144, 4128, 4112
143 static bool bSinCosTablesInitialized =
false;
145 if (bSinCosTablesInitialized)
148 for (
int i = -10; i < 370; i++)
155 bSinCosTablesInitialized =
true;
169 printf(
"error: input and output image do not match for ImageProcessor::GeneralFilter\n");
173 if (nMaskSize < 3 || (nMaskSize + 1) % 2 != 0)
175 printf(
"error: nMaskSize must be 2 * k + 1 with k >= 1 for ImageProcessor::GeneralFilter\n");
182 pSaveOutputImage = pOutputImage;
188 const int umax = pInputImage->
width - nMaskSize + 1;
189 const int vmax = pInputImage->
height - nMaskSize + 1;
192 unsigned char *output = pOutputImage->
pixels;
194 const int diff = (nMaskSize - 1) * (pInputImage->
width + 1) / 2;
202 for (
int u = 0; u < umax; u++, offset++)
206 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
208 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
209 sum += input[offset2] * pKernel[offset3];
212 output[
offset] = (
unsigned char) abs(sum);
220 for (
int u = 0; u < umax; u++, offset++)
224 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
226 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
227 sum += input[offset2] * pKernel[offset3];
230 output[
offset] = (
unsigned char) sum;
241 for (
int u = 0; u < umax; u++, offset++)
245 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
247 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
248 sum += input[offset2] * pKernel[offset3];
251 output[
offset] = (
unsigned char) (abs(sum) / nDivider);
259 for (
int u = 0; u < umax; u++, offset++)
263 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
265 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
266 sum += input[offset2] * pKernel[offset3];
269 output[
offset] = (
unsigned char) (sum / nDivider);
275 if (pSaveOutputImage)
277 CopyImage(pOutputImage, pSaveOutputImage);
289 printf(
"error: input and output image do not match for ImageProcessor::GeneralFilter\n");
293 if (nMaskSize < 3 || (nMaskSize + 1) % 2 != 0)
295 printf(
"error: nMaskSize must be 2 * k + 1 with k >= 1 for ImageProcessor::GeneralFilter\n");
303 const int umax = width - nMaskSize + 1;
304 const int vmax = height - nMaskSize + 1;
307 short *output = pOutputImage->
pixels;
309 const int diff = (nMaskSize - 1) * (width + 1) / 2;
317 for (
int u = 0; u < umax; u++, offset++)
321 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
323 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
324 sum += input[offset2] * pKernel[offset3];
327 output[
offset] = (short) abs(sum);
335 for (
int u = 0; u < umax; u++, offset++)
339 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
341 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
342 sum += input[offset2] * pKernel[offset3];
345 output[
offset] = (short) sum;
356 for (
int u = 0; u < umax; u++, offset++)
360 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
362 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
363 sum += input[offset2] * pKernel[offset3];
366 output[
offset] = (short) (abs(sum) / nDivider);
374 for (
int u = 0; u < umax; u++, offset++)
378 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
380 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
381 sum += input[offset2] * pKernel[offset3];
384 output[
offset] = (short) (sum / nDivider);
398 printf(
"error: input image and output matrix do not match for ImageProcessor::GeneralFilter\n");
402 if (nMaskSize < 3 || (nMaskSize + 1) % 2 != 0)
404 printf(
"error: nMaskSize must be 2 * k + 1 with k >= 1 for ImageProcessor::GeneralFilter\n");
412 const int umax = width - nMaskSize + 1;
413 const int vmax = height - nMaskSize + 1;
416 float *output = pOutputMatrix->
data;
420 const int k = (nMaskSize - 1) / 2;
422 for (
int v = 0;
v < vmax;
v++)
424 for (
int u = 0; u < umax; u++)
428 for (
int i = 0; i < nMaskSize; i++)
430 for (
int j = 0; j < nMaskSize; j++)
431 sum += input[(
v + i) * width + (u + j)] * pKernel[i * nMaskSize + j];
434 output[(
v + k) * width + (u + k)] = float(abs(sum)) / nDivider;
440 const int diff = (nMaskSize - 1) * (width + 1) / 2;
448 for (
int u = 0; u < umax; u++, offset++)
452 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
454 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
455 sum += input[offset2] * pKernel[offset3];
458 output[
offset] = (float) abs(sum);
466 for (
int u = 0; u < umax; u++, offset++)
470 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
472 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
473 sum += input[offset2] * pKernel[offset3];
476 output[
offset] = (float) sum;
487 for (
int u = 0; u < umax; u++, offset++)
491 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
493 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
494 sum += input[offset2] * pKernel[offset3];
497 output[
offset] = float(abs(sum)) / nDivider;
505 for (
int u = 0; u < umax; u++, offset++)
509 for (
int i = 0, offset2 = offset - diff, offset3 = 0; i < nMaskSize; i++, offset2 += umax - 1)
511 for (
int j = 0; j < nMaskSize; j++, offset2++, offset3++)
512 sum += input[offset2] * pKernel[offset3];
515 output[
offset] = float(sum) / nDivider;
540 printf(
"error: input and output image do not match for ImageProcessor::GaussianSmooth5x5\n");
544 if (pInputImage->
width < 5 || pInputImage->
height < 5)
546 printf(
"error: image must be at least of size 5x5 for ImageProcessor::GaussianSmooth5x5\n");
569 const int nPixels = width *
height;
576 imageHeaderOutputGrayscale.
pixels = pOutputImage->
pixels;
580 imageHeaderInputGrayscale.
pixels = pInputImage->
pixels + nPixels;
581 imageHeaderOutputGrayscale.
pixels = pOutputImage->
pixels + nPixels;
585 imageHeaderInputGrayscale.
pixels = pInputImage->
pixels + 2 * nPixels;
586 imageHeaderOutputGrayscale.
pixels = pOutputImage->
pixels + 2 * nPixels;
595 const int width2 = width << 1;
598 unsigned char *temp = pTempImage->
pixels;
599 unsigned char *output = pOutputImage->
pixels;
604 for (y = 0, offset = 0; y <
height; y++)
606 temp[
offset] = (11 * input[
offset] + (input[offset + 1] << 2) + input[offset + 2] + 8) >> 4;
607 temp[offset + 1] = (5 * input[
offset] + 6 * input[offset + 1] + (input[offset + 2] << 2) + input[offset + 3] + 8) >> 4;
611 for (x = 4; x <
width; x++, offset++)
612 temp[offset] = (input[offset - 2] + (input[offset - 1] << 2) + 6 * input[
offset] + (input[offset + 1] << 2) + input[offset + 2] + 8) >> 4;
614 temp[
offset] = (input[offset - 2] + (input[offset - 1] << 2) + 6 * input[offset] + 5 * input[offset + 1] + 8) >> 4;
615 temp[offset + 1] = (input[offset - 1] + (input[
offset] << 2) + 11 * input[offset + 1] + 8) >> 4;
620 for (x = 0, offset = 0; x <
width; x++, offset++)
622 output[
offset] = (11 * temp[
offset] + (temp[offset +
width] << 2) + temp[offset + width2] + 8) >> 4;
623 output[offset +
width] = (5 * temp[
offset] + 6 * temp[offset +
width] + (temp[offset + width2] << 2) + temp[offset + 3 * width] + 8) >> 4;
627 for (y = 4, offset = width << 1; y <
height; y++)
628 for (x = 0; x <
width; x++, offset++)
629 output[offset] = (temp[offset - width2] + (temp[offset - width] << 2) + 6 * temp[
offset] + (temp[offset +
width] << 2) + temp[offset + width2] + 8) >> 4;
631 for (x = 0, offset = (height - 2) *
width; x <
width; x++, offset++)
633 output[
offset] = (temp[offset - width2] + (temp[offset -
width] << 2) + 6 * temp[offset] + 5 * temp[offset + width] + 8) >> 4;
634 output[offset +
width] = (temp[offset -
width] + (temp[
offset] << 2) + 11 * temp[offset + width] + 8) >> 4;
651 printf(
"error: input and output image do not match for ImageProcessor::AverageFilter\n");
658 pSaveOutputImage = pOutputImage;
664 const int maxj = pInputImage->
width - 1, maxi = pInputImage->
height - 1;
667 unsigned char *output = pOutputImage->
pixels;
669 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
671 for (
int j = 1; j < maxj; j++, offset++)
674 input[offset - width - 1] + input[offset -
width] + input[offset - width + 1] +
675 input[offset - 1] + input[
offset] + input[offset + 1] +
676 input[offset + width - 1] + input[offset +
width] + input[offset + width + 1]
681 if (pSaveOutputImage)
701 printf(
"error: input and output image do not match for ImageProcessor::AverageFilter\n");
705 if (nMaskSize < 3 || (nMaskSize + 1) % 2 != 0)
707 printf(
"error: nMaskSize must be 2 * k + 1 with k >= 1 for ImageProcessor::AverageFilter\n");
720 const int frame = (nMaskSize - 1) / 2;
721 const int area_size = nMaskSize*nMaskSize;
723 const int maxx = width - 2*frame;
724 const int maxy = height - 2*frame;
728 unsigned char *output = pOutputImage->
pixels;
730 for (
int y = 1;
y < maxy;
y++)
732 const int line_offset = (
y + frame)*width + frame;
733 for (
int x = 1;
x < maxx;
x++)
735 int p1 = (
y-1)*width +
x - 1;
738 output[line_offset +
x] = (input[p3 + nMaskSize] - input[p3] - input[p1 + nMaskSize] + input[p1]) / area_size;
751 pInputImage->
type != pOutputImage->
type)
753 printf(
"error: input and output image do not match for ImageProcessor::GaussianSmooth3x3\n");
757 if (pInputImage->
width < 3 || pInputImage->
height < 3)
759 printf(
"error: image must be at least of size 3x3 for ImageProcessor::GaussianSmooth3x3\n");
766 pSaveOutputImage = pOutputImage;
770 const int maxj = pInputImage->
width - 1, maxi = pInputImage->
height - 1;
771 const unsigned char *
p = pInputImage->
pixels;
772 unsigned char *output = pOutputImage->
pixels;
778 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
780 for (
int j = 1; j < maxj; j++, offset++)
783 p[offset - width - 1] + (p[offset -
width] << 1) + p[offset - width + 1] +
784 (p[offset - 1] << 1) + (p[
offset] << 2) + (p[offset + 1] << 1) +
785 p[offset + width - 1] + (p[offset +
width] << 1) + p[offset + width + 1] + 8
795 for (
int i = 1; i < maxi; i++)
797 for (
int j = 1; j < maxj; j++)
800 p[offset - width - 3] + (p[offset -
width] << 1) + p[offset - width + 3] +
801 (p[offset - 3] << 1) + (p[
offset] << 2) + (p[offset + 3] << 1) +
802 p[offset + width - 3] + (p[offset +
width] << 1) + p[offset + width + 3] + 8
808 p[offset - width - 3] + (p[offset -
width] << 1) + p[offset - width + 3] +
809 (p[offset - 3] << 1) + (p[
offset] << 2) + (p[offset + 3] << 1) +
810 p[offset + width - 3] + (p[offset +
width] << 1) + p[offset + width + 3] + 8
816 p[offset - width - 3] + (p[offset -
width] << 1) + p[offset - width + 3] +
817 (p[offset - 3] << 1) + (p[
offset] << 2) + (p[offset + 3] << 1) +
818 p[offset + width - 3] + (p[offset +
width] << 1) + p[offset + width + 3] + 8
829 if (pSaveOutputImage)
830 CopyFrame(pSaveOutputImage, pOutputImage);
834 if (pSaveOutputImage)
836 CopyImage(pOutputImage, pSaveOutputImage);
850 if (!
SobelX(pInputImage, &image, bAbsoluteValue))
860 if (!
SobelY(pInputImage, &image, bAbsoluteValue))
873 printf(
"error: input and output image do not match for ImageProcessor::SobelY\n");
879 const int maxj = pInputImage->
width - 1, maxi = pInputImage->
height - 1;
882 short *output = pOutputImage->
pixels;
886 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
888 for (
int j = 1; j < maxj; j++, offset++)
891 abs(input[offset + width - 1] + (input[offset + width] << 1) + input[offset + width + 1] -
892 input[offset - width - 1] - (input[offset - width] << 1) - input[offset - width + 1]);
898 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
900 for (
int j = 1; j < maxj; j++, offset++)
903 input[offset + width - 1] + (input[offset +
width] << 1) + input[offset + width + 1] -
904 input[offset - width - 1] - (input[offset - width] << 1) - input[offset - width + 1];
921 printf(
"error: input and output image do not match for ImageProcessor::SobelX\n");
927 const int maxj = pInputImage->
width - 1, maxi = pInputImage->
height - 1;
930 short *output = pOutputImage->
pixels;
934 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
936 for (
int j = 1; j < maxj; j++, offset++)
939 abs(input[offset - width + 1] + (input[offset + 1] << 1) + input[offset + width + 1] -
940 input[offset - width - 1] - (input[offset - 1] << 1) - input[offset + width - 1]);
946 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
948 for (
int j = 1; j < maxj; j++, offset++)
951 input[offset - width + 1] + (input[offset + 1] << 1) + input[offset + width + 1] -
952 input[offset - width - 1] - (input[offset - 1] << 1) - input[offset + width - 1];
967 if (!
PrewittX(pInputImage, &image, bAbsoluteValue))
977 if (!
PrewittY(pInputImage, &image, bAbsoluteValue))
990 printf(
"error: input and output image do not match for ImageProcessor::PrewittY\n");
996 const int maxj = pInputImage->
width - 1, maxi = pInputImage->
height - 1;
999 short *output = pOutputImage->
pixels;
1003 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
1005 for (
int j = 1; j < maxj; j++, offset++)
1008 abs(input[offset + width - 1] + input[offset + width] + input[offset + width + 1] -
1009 input[offset - width - 1] - input[offset - width] - input[offset - width + 1]);
1015 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
1017 for (
int j = 1; j < maxj; j++, offset++)
1020 input[offset + width - 1] + input[offset +
width] + input[offset + width + 1] -
1021 input[offset - width - 1] - input[offset -
width] - input[offset - width + 1];
1038 printf(
"error: input and output image do not match for ImageProcessor::PrewittX\n");
1044 const int maxj = pInputImage->
width - 1, maxi = pInputImage->
height - 1;
1047 short *output = pOutputImage->
pixels;
1051 for (
int i = 1; i < maxi; ++i)
1053 int offset = width * i + 1;
1054 for (
int j = 1; j < maxj; ++j, ++
offset)
1057 abs(input[offset - width + 1] + input[offset + 1] + input[offset + width + 1] -
1058 input[offset - width - 1] - input[offset - 1] - input[offset + width - 1]);
1064 for (
int i = 1; i < maxi; ++i)
1066 int offset = width * i + 1;
1067 for (
int j = 1; j < maxj; ++j, ++
offset)
1070 input[offset - width + 1] + input[offset + 1] + input[offset + width + 1] -
1071 input[offset - width - 1] - input[offset - 1] - input[offset + width - 1];
1086 if (!
Laplace1(pInputImage, &image, bAbsoluteValue))
1098 if (!
Laplace2(pInputImage, &image, bAbsoluteValue))
1113 printf(
"error: input and output image do not match for ImageProcessor::Laplace1\n");
1119 const int maxj = pInputImage->
width - 1, maxi = pInputImage->
height - 1;
1122 short *output = pOutputImage->
pixels;
1126 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
1128 for (
int j = 1; j < maxj; j++, offset++)
1131 abs(input[offset - width] +
1132 input[offset - 1] - (input[offset] << 2) + input[offset + 1] +
1133 input[offset + width]);
1139 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
1141 for (
int j = 1; j < maxj; j++, offset++)
1144 input[offset -
width] +
1145 input[offset - 1] - (input[
offset] << 2) + input[offset + 1] +
1146 input[offset + width];
1163 printf(
"error: input and output image do not match for ImageProcessor::Laplace2\n");
1169 const int maxj = pInputImage->
width - 1, maxi = pInputImage->
height - 1;
1172 short *output = pOutputImage->
pixels;
1176 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
1178 for (
int j = 1; j < maxj; j++, offset++)
1181 abs(input[offset - width - 1] + input[offset - width] + input[offset - width + 1] +
1182 input[offset - 1] - (input[offset] << 3) + input[offset + 1] +
1183 input[offset + width - 1] + input[offset + width] + input[offset + width + 1]);
1189 for (
int i = 1,
offset = width + 1; i < maxi; i++,
offset += 2)
1191 for (
int j = 1; j < maxj; j++, offset++)
1194 input[offset - width - 1] + input[offset -
width] + input[offset - width + 1] +
1195 input[offset - 1] - (input[
offset] << 3) + input[offset + 1] +
1196 input[offset + width - 1] + input[offset + width] + input[offset + width + 1];
1214 printf(
"error: input and output image do not match for ImageProcessor::CalculateGradientImagePrewitt\n");
1221 pSaveOutputImage = pOutputImage;
1227 const int maxu = pInputImage->
width - 1, maxv = pInputImage->
height - 1;
1230 unsigned char *output = pOutputImage->
pixels;
1234 for (
int u = 1; u < maxu; u++, offset++)
1237 abs(input[offset + width - 1] + input[offset + width] + input[offset + width + 1] -
1238 input[offset - width - 1] - input[offset - width] - input[offset - width + 1]);
1241 abs(input[offset - width + 1] + input[offset + 1] + input[offset + width + 1] -
1242 input[offset - width - 1] - input[offset - 1] - input[offset + width - 1]);
1244 const int value = value_x > value_y ? value_x : value_y;
1250 if (pSaveOutputImage)
1252 CopyImage(pOutputImage, pSaveOutputImage);
1253 delete pOutputImage;
1268 printf(
"error: input and output image do not match for ImageProcessor::CalculateGradientImageSobel\n");
1275 pSaveOutputImage = pOutputImage;
1281 const int maxu = pInputImage->
width - 1, maxv = pInputImage->
height - 1;
1284 unsigned char *output = pOutputImage->
pixels;
1288 for (
int u = 1; u < maxu; u++, offset++)
1291 abs(input[offset + width - 1] + (input[offset + width] << 1) + input[offset + width + 1] -
1292 input[offset - width - 1] - (input[offset - width] << 1) - input[offset - width + 1]);
1295 abs(input[offset - width + 1] + (input[offset + 1] << 1) + input[offset + width + 1] -
1296 input[offset - width - 1] - (input[offset - 1] << 1) - input[offset + width - 1]);
1298 const int value = value_x > value_y ? value_x : value_y;
1304 if (pSaveOutputImage)
1306 CopyImage(pOutputImage, pSaveOutputImage);
1307 delete pOutputImage;
1319 printf(
"error: input and output image do not match for ImageProcessor::CalculateGradientImage\n");
1326 pSaveOutputImage = pOutputImage;
1332 const int maxu = pInputImage->
width - 1, maxv = pInputImage->
height - 1;
1335 unsigned char *output = pOutputImage->
pixels;
1341 for (
int u = 1; u < maxu; u++, offset++)
1343 const int value_x = abs(input[offset + width] - input[offset - width]);
1344 const int value_y = abs(input[offset + 1] - input[offset - 1]);
1345 const int value = value_x > value_y ? value_x : value_y;
1352 const unsigned char *input_r = pInputImage->
pixels;
1353 const unsigned char *input_g = pInputImage->
pixels + 1;
1354 const unsigned char *input_b = pInputImage->
pixels + 2;
1355 const int width3 = 3 *
width;
1357 for (
int v = 1,
offset = width3 + 3, output_offset = 0;
v < maxv;
v++,
offset += 6, output_offset += 2)
1359 for (
int u = 1; u < maxu; u++, offset += 3, output_offset++)
1361 const int r1 = abs(input_r[offset + 3] - input_r[offset - 3]);
1362 const int r2 = abs(input_r[offset + width3] - input_r[offset - width3]);
1363 const int g1 = abs(input_g[offset + 3] - input_g[offset - 3]);
1364 const int g2 = abs(input_g[offset + width3] - input_g[offset - width3]);
1365 const int b1 = abs(input_b[offset + 3] - input_b[offset - 3]);
1366 const int b2 = abs(input_b[offset + width3] - input_b[offset - width3]);
1370 const int value = r > g ? (r > b ? r :
b) : (g > b ? g : b);
1371 output[output_offset] = value > 255 ? 255 :
value;
1376 if (pSaveOutputImage)
1378 CopyImage(pOutputImage, pSaveOutputImage);
1379 delete pOutputImage;
1390 printf(
"error: input and output image do not match for ImageProcessor::CalculateGradientImageBinary\n");
1397 pSaveOutputImage = pOutputImage;
1403 const int maxj = pInputImage->
width - 1, maxi = pInputImage->
height - 1;
1406 unsigned char *output = pOutputImage->
pixels;
1410 for (
int j = 0; j < maxj; j++,
offset++)
1416 if (pSaveOutputImage)
1418 CopyImage(pOutputImage, pSaveOutputImage);
1419 delete pOutputImage;
1433 printf(
"error: input and output image do not match for Dilate3x3\n");
1440 pSaveOutputImage = pOutputImage;
1450 unsigned char *output = pOutputImage->
pixels;
1452 int min_u, max_u, min_v, max_v;
1456 min_u = pROI->
min_x + 1;
1457 max_u = pROI->
max_x - 1;
1458 min_v = pROI->
min_y + 1;
1459 max_v = pROI->
max_y - 1;
1461 if (min_u < 1) min_u = 1;
1462 if (min_u > width - 2) min_u = width - 2;
1463 if (max_u < 1) max_u = 1;
1464 if (max_u > width - 2) max_u = width - 2;
1465 if (min_v < 1) min_v = 1;
1466 if (min_v > height - 2) min_v = height - 2;
1467 if (max_v < 1) max_v = 1;
1468 if (max_v > height - 2) max_v = height - 2;
1478 const int diff = width - (max_u - min_u + 1);
1480 bool *bLastY =
new bool[
width];
1481 memset(bLastY,
false, width *
sizeof(
bool));
1483 for (
int v = min_v,
offset = min_v * width + min_u;
v <= max_v;
v++,
offset += diff)
1485 bool bLastX =
false;
1487 for (
int u = min_u; u <= max_u; u++, offset++)
1495 output[offset + width + 1] = 255;
1499 output[offset - width + 1] = 255;
1500 output[offset + 1] = 255;
1501 output[offset + width + 1] = 255;
1510 output[offset + width - 1] = 255;
1511 output[offset +
width] = 255;
1512 output[offset + width + 1] = 255;
1516 output[offset - width - 1] = 255;
1517 output[offset -
width] = 255;
1518 output[offset - width + 1] = 255;
1519 output[offset - 1] = 255;
1521 output[offset + 1] = 255;
1522 output[offset + width - 1] = 255;
1523 output[offset +
width] = 255;
1524 output[offset + width + 1] = 255;
1542 if (pSaveOutputImage)
1545 delete pOutputImage;
1560 printf(
"error: input and output image do not match for Erode3x3\n");
1567 pSaveOutputImage = pOutputImage;
1577 unsigned char *output = pOutputImage->
pixels;
1579 int min_u, max_u, min_v, max_v;
1583 min_u = pROI->
min_x + 1;
1584 max_u = pROI->
max_x - 1;
1585 min_v = pROI->
min_y + 1;
1586 max_v = pROI->
max_y - 1;
1588 if (min_u < 1) min_u = 1;
1589 if (min_u > width - 2) min_u = width - 2;
1590 if (max_u < 1) max_u = 1;
1591 if (max_u > width - 2) max_u = width - 2;
1592 if (min_v < 1) min_v = 1;
1593 if (min_v > height - 2) min_v = height - 2;
1594 if (max_v < 1) max_v = 1;
1595 if (max_v > height - 2) max_v = height - 2;
1605 const int diff = width - (max_u - min_u + 1);
1607 bool *bLastY =
new bool[
width];
1608 memset(bLastY,
false, width *
sizeof(
bool));
1610 for (
int v = min_v,
offset = min_v * width + min_u;
v <= max_v;
v++,
offset += diff)
1612 bool bLastX =
false;
1614 for (
int u = min_u; u <= max_u; u++, offset++)
1620 if (!input[offset + width + 1])
1629 if (!input[offset - width + 1] || !input[offset + 1] || !input[offset + width + 1])
1644 if (!input[offset + width - 1] || !input[offset + width] || !input[offset + width + 1])
1656 if (!input[offset - width - 1] || !input[offset - width] || !input[offset - width + 1] ||
1657 !input[offset - 1] || !input[offset] || !input[offset + 1] ||
1658 !input[offset + width - 1] || !input[offset + width] || !input[offset + width + 1])
1676 if (pSaveOutputImage)
1679 delete pOutputImage;
1691 Dilate3x3(pInputImage, pOutputImage, pROI);
1697 printf(
"error: mask size is too small for ImageProcessor::Dilate\n");
1704 printf(
"error: input and output image do not match for ImageProcessor::Dilate\n");
1708 const int k = (nMaskSize - 1) / 2;
1713 pSaveOutputImage = pOutputImage;
1723 unsigned char *output = pOutputImage->
pixels;
1725 int min_u, max_u, min_v, max_v;
1729 min_u = pROI->
min_x + 1;
1730 max_u = pROI->
max_x - 1;
1731 min_v = pROI->
min_y + 1;
1732 max_v = pROI->
max_y - 1;
1734 if (min_u < k) min_u = k;
1735 if (min_u > width - 1 - k) min_u = width - 1 - k;
1736 if (max_u < k) max_u = k;
1737 if (max_u > width - 1 - k) max_u = width - 1 - k;
1738 if (min_v < k) min_v = k;
1739 if (min_v > height - 1 - k) min_v = height - 1 - k;
1740 if (max_v < k) max_v = k;
1741 if (max_v > height - 1 - k) max_v = height - 1 - k;
1746 max_u = width - 1 - k;
1748 max_v = height - 1 - k;
1751 const int diff = width - (max_u - min_u + 1);
1753 bool *bLastY =
new bool[
width];
1754 memset(bLastY,
false, width *
sizeof(
bool));
1756 for (
int v = min_v,
offset = min_v * width + min_u;
v <= max_v;
v++,
offset += diff)
1758 bool bLastX =
false;
1760 for (
int u = min_u; u <= max_u; u++, offset++)
1768 output[offset + k * width + k] = 255;
1772 for (
int i = -k; i <= k; i++)
1773 output[offset + i * width + k] = 255;
1782 for (
int i = -k; i <= k; i++)
1783 output[offset + k * width + i] = 255;
1787 for (
int i = -k; i <= k; i++)
1788 for (
int j = -k; j <= k; j++)
1789 output[offset + i * width + j] = 255;
1807 if (pSaveOutputImage)
1809 CopyImage(pOutputImage, pSaveOutputImage, pROI,
true);
1810 delete pOutputImage;
1820 Erode3x3(pInputImage, pOutputImage, pROI);
1826 printf(
"error: mask size is too small for ImageProcessor::Erode\n");
1833 printf(
"error: input and output image do not match for ImageProcessor::Erode\n");
1837 const int k = (nMaskSize - 1) / 2;
1842 pSaveOutputImage = pOutputImage;
1852 unsigned char *output = pOutputImage->
pixels;
1854 int min_u, max_u, min_v, max_v;
1858 min_u = pROI->
min_x + 1;
1859 max_u = pROI->
max_x - 1;
1860 min_v = pROI->
min_y + 1;
1861 max_v = pROI->
max_y - 1;
1863 if (min_u < k) min_u = k;
1864 if (min_u > width - 1 - k) min_u = width - 1 - k;
1865 if (max_u < k) max_u = k;
1866 if (max_u > width - 1 - k) max_u = width - 1 - k;
1867 if (min_v < k) min_v = k;
1868 if (min_v > height - 1 - k) min_v = height - 1 - k;
1869 if (max_v < k) max_v = k;
1870 if (max_v > height - 1 - k) max_v = height - 1 - k;
1875 max_u = width - 1 - k;
1877 max_v = height - 1 - k;
1880 const int diff = width - (max_u - min_u + 1);
1882 bool *bLastY =
new bool[
width];
1883 memset(bLastY,
false, width *
sizeof(
bool));
1885 for (
int v = min_v,
offset = min_v * width + min_u;
v <= max_v;
v++,
offset += diff)
1887 bool bLastX =
false;
1889 for (
int u = min_u; u <= max_u; u++)
1895 if (!input[offset + k * width + k])
1904 for (
int i = -k; i <= k; i++)
1905 if (!input[offset + i * width + k])
1918 for (
int i = -k; i <= k; i++)
1919 if (!input[offset + k * width + i])
1927 for (
int i = -k; i <= k; i++)
1928 for (
int j = -k; j <= k; j++)
1929 if (!input[offset + i * width + j])
1948 if (pSaveOutputImage)
1950 CopyImage(pOutputImage, pSaveOutputImage, pROI,
true);
1951 delete pOutputImage;
1963 printf(
"error: input and output image do not match for ImageProcessor::HistogramEqualization\n");
1967 const int nPixels = pInputImage->
width * pInputImage->
height;
1969 unsigned char *output = pOutputImage->
pixels;
1970 const float fNormalizeConstant = 255.0f / nPixels;
1971 int histogram[256] = { 0 };
1975 for (i = 0; i < nPixels; i++)
1976 histogram[input[i]]++;
1979 for (i = 1; i < 256; i++)
1980 histogram[i] += histogram[i - 1];
1982 for (i = 0; i < 256; i++)
1983 histogram[i] =
int(histogram[i] * fNormalizeConstant + 0.5f);
1986 for (i = 0; i < nPixels; i++)
1987 output[i] = histogram[input[i]];
1999 printf(
"error: input and output image do not match for ImageProcessor::ApplyAffinePointOperation\n");
2005 unsigned char *output = pOutputImage->
pixels;
2009 for (
int i = 0; i < nBytes; i++)
2011 const int v = int(a * input[i] + b);
2026 printf(
"error: input and output image do not match for ImageProcessor::Spread\n");
2030 const int nPixels = pInputImage->
width * pInputImage->
height;
2032 unsigned char min = 255, max = 0;
2035 for (
int i = 0; i < nPixels; i++)
2046 printf(
"error: input image is homogenous with gray value %i\n", min);
2050 const float a = 255.0f / (max - min);
2051 const float b = -(min * 255.0f) / (max - min);
2063 printf(
"error: input and output image do not match for ImageProcessor::HistogramStretching\n");
2067 const int nPixels = pInputImage->
width * pInputImage->
height;
2069 int histogram[256] = { 0 };
2073 for (i = 0; i < nPixels; i++)
2074 histogram[input[i]]++;
2077 for (i = 1; i < 256; i++)
2078 histogram[i] += histogram[i - 1];
2080 const float nMinValue = p_min * histogram[255];
2081 const float nMaxValue = p_max * histogram[255];
2082 int min = 0, max = 0;
2084 for (i = 0; i < 256; i++)
2086 if (histogram[i] >= nMinValue)
2093 for (i = 0; i < 256; i++)
2095 if (histogram[i] >= nMaxValue)
2104 printf(
"error: input image is homogenous with gray value %i\n", min);
2108 const float a = 255.0f / (max - min);
2109 const float b = -(min * 255.0f) / (max - min);
2122 printf(
"error: input and output image do not match for ImageProcessor::Invert\n");
2128 unsigned char *output = pOutputImage->
pixels;
2130 for (
int i = 0; i < nBytes; i++)
2131 output[i] = 255 - input[i];
2145 printf(
"error: input and output image do not match for ImageProcessor::ConvertImage\n");
2149 if (pInputImage->
type == pOutputImage->
type)
2151 CopyImage(pInputImage, pOutputImage, pROI,
true);
2155 const int nPixels = pInputImage->
width * pInputImage->
height;
2158 unsigned char *output = pOutputImage->
pixels;
2165 int min_x = pROI->
min_x;
2166 int max_x = pROI->
max_x;
2167 int min_y = pROI->
min_y;
2168 int max_y = pROI->
max_y;
2170 if (min_x < 0) min_x = 0;
2171 if (min_x > width - 1) min_x = width - 1;
2172 if (max_x < 0) max_x = 0;
2173 if (max_x > width - 1) max_x = width - 1;
2174 if (min_y < 0) min_y = 0;
2175 if (min_y > height - 1) min_y = height - 1;
2176 if (max_y < 0) max_y = 0;
2177 if (max_y > height - 1) max_y = height - 1;
2179 const int diff = width - (max_x - min_x + 1);
2180 const int diff_rgb = 3 * diff;
2188 for (
int y = min_y, offset_output = width * min_y + min_x, offset_input = 3 * offset_output;
y <= max_y;
y++, offset_output += diff, offset_input += diff_rgb)
2189 for (
int x = min_x;
x <= max_x;
x++, offset_output++, offset_input += 3)
2190 output[offset_output] = (input[offset_input] + (input[offset_input + 1] << 1) + input[offset_input + 2] + 2) >> 2;
2194 for (
int y = min_y, offset_output = width * min_y + min_x, offset_input = 3 * offset_output;
y <= max_y;
y++, offset_output += diff, offset_input += diff_rgb)
2195 for (
int x = min_x;
x <= max_x;
x++, offset_output++, offset_input += 3)
2196 output[offset_output] = (9797 * input[offset_input] + 19235 * input[offset_input + 1] + 3736 * input[offset_input + 2] + 16384) >> 15;
2201 unsigned char *pHelperR = output;
2202 unsigned char *pHelperG = pHelperR + nPixels;
2203 unsigned char *pHelperB = pHelperG + nPixels;
2205 for (
int y = min_y, offset_output = width * min_y + min_x, offset_input = 3 * offset_output;
y <= max_y;
y++, offset_output += diff, offset_input += diff_rgb)
2206 for (
int x = min_x;
x <= max_x;
x++, offset_output++, offset_input += 3)
2208 pHelperR[offset_output] = input[offset_input];
2209 pHelperG[offset_output] = input[offset_input + 1];
2210 pHelperB[offset_output] = input[offset_input + 2];
2216 const unsigned char *pHelperR =
input;
2217 const unsigned char *pHelperG = pHelperR + nPixels;
2218 const unsigned char *pHelperB = pHelperG + nPixels;
2224 for (
int y = min_y,
offset = width * min_y + min_x;
y <= max_y;
y++,
offset += diff)
2225 for (
int x = min_x;
x <= max_x;
x++, offset++)
2226 output[offset] = (pHelperR[offset] + (pHelperG[offset] << 1) + pHelperB[
offset] + 2) >> 2;
2230 for (
int y = min_y,
offset = width * min_y + min_x;
y <= max_y;
y++,
offset += diff)
2231 for (
int x = min_x;
x <= max_x;
x++, offset++)
2232 output[offset] = (9797 * pHelperR[offset] + 19235 * pHelperG[offset] + 3736 * pHelperB[offset] + 16384) >> 15;
2237 for (
int y = min_y, input_offset = width * min_y + min_x, output_offset = 3 * input_offset;
y <= max_y;
y++, input_offset += diff, output_offset += diff_rgb)
2238 for (
int x = min_x;
x <= max_x;
x++, input_offset++, output_offset += 3)
2240 output[output_offset] = pHelperR[input_offset];
2241 output[output_offset + 1] = pHelperG[input_offset];
2242 output[output_offset + 2] = pHelperB[input_offset];
2250 for (
int y = min_y, offset_input = width * min_y + min_x, offset_output = 3 * offset_input;
y <= max_y;
y++, offset_output += diff_rgb, offset_input += diff)
2251 for (
int x = min_x;
x <= max_x;
x++, offset_output += 3, offset_input++)
2253 output[offset_output + 2] = input[offset_input];
2254 output[offset_output + 1] = input[offset_input];
2255 output[offset_output] = input[offset_input];
2260 unsigned char *pHelperR = output;
2261 unsigned char *pHelperG = pHelperR + nPixels;
2262 unsigned char *pHelperB = pHelperG + nPixels;
2264 for (
int y = min_y,
offset = width * min_y + min_x;
y <= max_y;
y++,
offset += diff)
2265 for (
int x = min_x;
x <= max_x;
x++, offset++)
2266 pHelperR[offset] = pHelperG[offset] = pHelperB[offset] = input[offset];
2278 for (
int offset = 0, i = 0; i < nPixels; i++,
offset += 3)
2279 output[i] = (input[offset] + (input[offset + 1] << 1) + input[offset + 2] + 2) >> 2;
2283 for (
int offset = 0, i = 0; i < nPixels; i++,
offset += 3)
2284 output[i] = (9797 * input[offset] + 19235 * input[offset + 1] + 3736 * input[offset + 2] + 16384) >> 15;
2289 unsigned char *pHelperR = output;
2290 unsigned char *pHelperG = pHelperR + nPixels;
2291 unsigned char *pHelperB = pHelperG + nPixels;
2293 for (
int offset = 0, i = 0; i < nPixels; i++,
offset += 3)
2295 pHelperR[i] = input[
offset];
2296 pHelperG[i] = input[offset + 1];
2297 pHelperB[i] = input[offset + 2];
2303 const unsigned char *pHelperR =
input;
2304 const unsigned char *pHelperG = pHelperR + nPixels;
2305 const unsigned char *pHelperB = pHelperG + nPixels;
2311 for (
int i = 0; i < nPixels; i++)
2312 output[i] = (pHelperR[i] + (pHelperG[i] << 1) + pHelperB[i] + 2) >> 2;
2316 for (
int i = 0; i < nPixels; i++)
2317 output[i] = (9797 * pHelperR[i] + 19235 * pHelperG[i] + 3736 * pHelperB[i] + 16384) >> 15;
2322 for (
int offset = 0, i = 0; i < nPixels; i++,
offset += 3)
2324 output[
offset] = pHelperR[i];
2325 output[offset + 1] = pHelperG[i];
2326 output[offset + 2] = pHelperB[i];
2334 for (
int offset = 0, i = 0; i < nPixels; i++,
offset += 3)
2336 output[offset + 2] = input[i];
2337 output[offset + 1] = input[i];
2338 output[
offset] = input[i];
2343 unsigned char *pHelperR = output;
2344 unsigned char *pHelperG = pHelperR + nPixels;
2345 unsigned char *pHelperB = pHelperG + nPixels;
2347 for (
int i = 0; i < nPixels; i++)
2348 pHelperR[i] = pHelperG[i] = pHelperB[i] = input[i];
2363 printf(
"error: ImageProcessor::ConvertImage cannot convert a single channel float image into mulitple channel byte image\n");
2369 printf(
"error: ImageProcessor::ConvertImage cannot convert a 3 channel float image into single channel byte image\n");
2375 printf(
"error: input and output image dimensions do not match for ImageProcessor::ConvertImage\n");
2379 const int nPixels = pInputImage->
width * pInputImage->
height;
2381 unsigned char* output = pOutputImage->
pixels;
2386 int pixelChannelIndex;
2393 for (i = 0; i < nPixels; i++)
2399 if (input[pixelChannelIndex] > max[j])
2401 max[j] = input[pixelChannelIndex];
2404 if (input[pixelChannelIndex] < min[j])
2406 min[j] = input[pixelChannelIndex];
2416 if((max[i] - min[i]) != 0.0f)
2418 factor[i] = 255.0f / max[i] - min[i];
2426 for (i = 0; i < nPixels; i++)
2432 output[pixelChannelIndex] = (
unsigned char) ((input[pixelChannelIndex] - min[j]) * factor[j]);
2441 if(min[i] < 0.0f || max[i] > 255.0f)
2443 printf(
"error: float input image values exceed value range of output byte image in ImageProcessor::ConvertImage. Equalization required!\n");
2448 for (i = 0; i < nPixels; i++)
2454 output[pixelChannelIndex] = (
unsigned char) input[pixelChannelIndex];
2467 printf(
"error: ImageProcessor::ConvertImage cannot convert a single channel byte image into single channel byte image\n");
2473 printf(
"error: ImageProcessor::ConvertImage cannot convert a single channel byte image into 3-channel float image\n");
2479 printf(
"error: input and output image dimensions do not match for ImageProcessor::ConvertImage\n");
2483 const int nPixels = pInputImage->
width * pInputImage->
height;
2485 float *output = pOutputImage->
pixels;
2487 int pixelChannelIndex;
2489 for (i = 0; i < nPixels; i++)
2495 output[pixelChannelIndex] = (float) input[pixelChannelIndex];
2507 printf(
"error: input matrix and output image do not match for ImageProcessor::ConvertImage\n");
2511 const int nPixels = pInputMatrix->
columns * pInputMatrix->
rows;
2512 const float *
input = pInputMatrix->
data;
2513 unsigned char *output = pOutputImage->
pixels;
2514 float min = FLT_MAX, max = -FLT_MAX;
2517 for (i = 0; i < nPixels; i++)
2526 const float divider = max - min;
2528 if (divider == 0.0f)
2534 const float factor = 255.0f / divider;
2536 for (i = 0; i < nPixels; i++)
2537 output[i] = (
unsigned char) ((input[i] - min) * factor);
2547 printf(
"error: input image and output matrix do not match for ImageProcessor::ConvertImage\n");
2551 const int nPixels = pOutputMatrix->
columns * pOutputMatrix->
rows;
2553 float *output = pOutputMatrix->
data;
2555 for (
int i = 0; i < nPixels; i++)
2556 output[i] = input[i];
2565 printf(
"error: input matrix and output image do not match for ImageProcessor::ConvertImage\n");
2569 const int nPixels = pInputImage->
width * pInputImage->
height;
2571 unsigned char *output = pOutputImage->
pixels;
2572 short min = SHRT_MAX, max = SHRT_MIN;
2575 for (i = 0; i < nPixels; i++)
2584 const short divider = max - min;
2592 for (i = 0; i < nPixels; i++)
2593 output[i] = (
unsigned char) ((255 * (input[i] - min)) / divider);
2603 printf(
"error: input image and output matrix do not match for ImageProcessor::ConvertImage\n");
2607 const int nPixels = pOutputImage->
width * pOutputImage->
height;
2609 short *output = pOutputImage->
pixels;
2611 for (
int i = 0; i < nPixels; i++)
2612 output[i] = (
short) input[i];
2621 printf(
"error: input image and output matrix do not match for ImageProcessor::ConvertImage\n");
2625 const int nPixels = pOutputImage->
width * pOutputImage->
height;
2627 int *output = pOutputImage->
pixels;
2629 for (
int i = 0; i < nPixels; i++)
2630 output[i] = (
int) input[i];
2639 printf(
"error: input matrix and output image do not match for ImageProcessor::ConvertImage\n");
2643 const int nPixels = pInputImage->
width * pInputImage->
height;
2645 unsigned char *output = pOutputImage->
pixels;
2646 int min = INT_MAX, max = INT_MIN;
2649 for (i = 0; i < nPixels; i++)
2658 const int divider = max - min;
2666 for (i = 0; i < nPixels; i++)
2667 output[i] = (
unsigned char) ((255 * (input[i] - min)) / divider);
2678 printf(
"error: input image and output matrix do not match for ImageProcessor::ConvertMatrix\n");
2682 const int nElements = pOutputMatrix->
rows * pOutputMatrix->
columns;
2683 const float *
input = pInputMatrix->
data;
2684 double *output = pOutputMatrix->
data;
2686 for (
int i = 0; i < nElements; i++)
2687 output[i] = (
double) input[i];
2696 printf(
"error: input image and output matrix do not match for ImageProcessor::ConvertMatrix\n");
2700 const int nElements = pOutputMatrix->
rows * pOutputMatrix->
columns;
2701 const double *
input = pInputMatrix->
data;
2702 float *output = pOutputMatrix->
data;
2704 for (
int i = 0; i < nElements; i++)
2705 output[i] = (
float) input[i];
2713 if (!pROI || bUseSameSize)
2717 printf(
"error: input and output image do not match for ImageProcessor::CopyImage\n");
2721 else if (pROI && !bUseSameSize)
2726 if (w != pOutputImage->
width || pOutputImage->
height != h || pInputImage->
type != pOutputImage->
type)
2728 printf(
"error: ROI and output image do not match for ImageProcessor::CopyImage\n");
2739 unsigned char *output = pOutputImage->
pixels;
2741 int min_x = pROI->
min_x;
2742 int max_x = pROI->
max_x;
2743 int min_y = pROI->
min_y;
2744 int max_y = pROI->
max_y;
2748 if (min_x < 0 || min_x > width - 1 || max_x < 0 || max_x > width - 1 ||
2749 min_y < 0 || min_y > height - 1 || max_y < 0 || max_y > height - 1)
2751 printf(
"error: ROI is out of image in ImageProcessor::CopyImage\n");
2756 if (min_x < 0) min_x = 0;
2757 if (min_x > width - 1) min_x = width - 1;
2758 if (max_x < 0) max_x = 0;
2759 if (max_x > width - 1) max_x = width - 1;
2760 if (min_y < 0) min_y = 0;
2761 if (min_y > height - 1) min_y = height - 1;
2762 if (max_y < 0) max_y = 0;
2763 if (max_y > height - 1) max_y = height - 1;
2767 const int size = max_x - min_x + 1;
2772 memcpy(output + offset, input + offset, size);
2776 for (
int y = min_y,
offset = width * min_y + min_x, output_offset = 0;
y <= max_y;
y++,
offset +=
width, output_offset +=
size)
2777 memcpy(output + output_offset, input + offset, size);
2782 const int size = 3 * (max_x - min_x + 1);
2783 const int width3 = 3 *
width;
2787 for (
int y = min_y,
offset = 3 * (width * min_y + min_x);
y <= max_y;
y++,
offset += width3)
2788 memcpy(output + offset, input + offset, size);
2792 for (
int y = min_y,
offset = 3 * (width * min_y + min_x), output_offset = 0;
y <= max_y;
y++,
offset += width3, output_offset +=
size)
2793 memcpy(output + output_offset, input + offset, size);
2798 const int size = max_x - min_x + 1;
2800 unsigned char *pHelperR = output;
2801 unsigned char *pHelperG = pHelperR + width *
height;
2802 unsigned char *pHelperB = pHelperG + width *
height;
2808 memcpy(pHelperR + offset, input + offset, size);
2809 memcpy(pHelperG + offset, input + offset, size);
2810 memcpy(pHelperB + offset, input + offset, size);
2815 for (
int y = min_y,
offset = 3 * (width * min_y + min_x), output_offset = 0;
y <= max_y;
y++,
offset +=
width, output_offset +=
size)
2817 memcpy(pHelperR + output_offset, input + offset, size);
2818 memcpy(pHelperG + output_offset, input + offset, size);
2819 memcpy(pHelperB + output_offset, input + offset, size);
2834 if (!pROI || bUseSameSize)
2838 printf(
"error: input and output image do not match for ImageProcessor::CopyImage\n");
2842 else if (pROI && !bUseSameSize)
2847 if (w != pOutputImage->
width || pOutputImage->
height != h)
2849 printf(
"error: ROI and output image do not match for ImageProcessor::CopyImage\n");
2860 short *output = pOutputImage->
pixels;
2862 int min_x = pROI->
min_x;
2863 int max_x = pROI->
max_x;
2864 int min_y = pROI->
min_y;
2865 int max_y = pROI->
max_y;
2869 if (min_x < 0 || min_x > width - 1 || max_x < 0 || max_x > width - 1 ||
2870 min_y < 0 || min_y > height - 1 || max_y < 0 || max_y > height - 1)
2872 printf(
"error: ROI is out of image in ImageProcessor::CopyImage\n");
2877 if (min_x < 0) min_x = 0;
2878 if (min_x > width - 1) min_x = width - 1;
2879 if (max_x < 0) max_x = 0;
2880 if (max_x > width - 1) max_x = width - 1;
2881 if (min_y < 0) min_y = 0;
2882 if (min_y > height - 1) min_y = height - 1;
2883 if (max_y < 0) max_y = 0;
2884 if (max_y > height - 1) max_y = height - 1;
2888 const int diff = width - (max_x - min_x + 1);
2890 for (
int y = min_y,
offset = width * min_y + min_x;
y <= max_y;
y++,
offset += diff)
2891 for (
int x = min_x;
x <= max_x;
x++, offset++)
2892 output[offset] = input[offset];
2896 const int diff = width - (max_x - min_x + 1);
2898 for (
int y = min_y,
offset = width * min_y + min_x, output_offset = 0;
y <= max_y;
y++,
offset += diff)
2899 for (
int x = min_x;
x <= max_x;
x++, offset++, output_offset++)
2900 output[output_offset] = input[offset];
2916 printf(
"error: input and output matrix do not match for ImageProcessor::CopyMatrix\n");
2920 memcpy(pOutputMatrix->
data, pInputMatrix->
data, pInputMatrix->
rows * pInputMatrix->
columns *
sizeof(
float));
2929 printf(
"error: input and output matrix do not match for ImageProcessor::CopyMatrix\n");
2933 memcpy(pOutputMatrix->
data, pInputMatrix->
data, pInputMatrix->
rows * pInputMatrix->
columns *
sizeof(
double));
2948 int min_x = pROI->
min_x;
2949 int max_x = pROI->
max_x;
2950 int min_y = pROI->
min_y;
2951 int max_y = pROI->
max_y;
2953 if (min_x < 0) min_x = 0;
2954 if (min_x > width - 1) min_x = width - 1;
2955 if (max_x < 0) max_x = 0;
2956 if (max_x > width - 1) max_x = width - 1;
2957 if (min_y < 0) min_y = 0;
2958 if (min_y > height - 1) min_y = height - 1;
2959 if (max_y < 0) max_y = 0;
2960 if (max_y > height - 1) max_y = height - 1;
2964 const int size = max_x - min_x + 1;
2967 memset(pixels + offset, 0, size);
2971 const int size = 3 * (max_x - min_x + 1);
2972 const int width3 = 3 *
width;
2974 for (
int y = min_y,
offset = 3 * (width * min_y + min_x);
y <= max_y;
y++,
offset += width3)
2975 memset(pixels, 0, size);
2979 const int size = max_x - min_x + 1;
2981 unsigned char *pHelperR =
pixels;
2982 unsigned char *pHelperG = pHelperR + width *
height;
2983 unsigned char *pHelperB = pHelperG + width *
height;
2987 memset(pHelperR + offset, 0, size);
2988 memset(pHelperG + offset, 0, size);
2989 memset(pHelperB + offset, 0, size);
3029 memset(pixels, 0, width);
3030 memset(pixels + width * (height - 1), 0, width);
3036 pixels[offset + width - 1] = 0;
3041 const int width3 = 3 *
width;
3044 memset(pixels, 0, width3);
3045 memset(pixels + width3 * (height - 1), 0, width3);
3050 pixels[
offset] = pixels[offset + 1] = pixels[offset + 2] = 0;
3051 pixels[offset + width3 - 3] = pixels[offset + width3 - 2] = pixels[offset + width3 - 1] = 0;
3063 memset(pixels, 0, width *
sizeof(
short));
3064 memset(pixels + width * (height - 1), 0, width *
sizeof(
short));
3070 pixels[offset + width - 1] = 0;
3081 memset(pixels, 0, width *
sizeof(
int));
3082 memset(pixels + width * (height - 1), 0, width *
sizeof(
int));
3088 pixels[offset + width - 1] = 0;
3096 printf(
"error: input and output images do not match for ImageProcessor::CopyFrame\n");
3105 unsigned char *output = pOutputImage->
pixels;
3112 memcpy(output, input, width);
3113 memcpy(output + width * (height - 1), input + width * (height - 1), width);
3116 const unsigned int offset2 = width - 1;
3117 for (
int y = 1;
y < height-1;
y++, offset +=
width)
3120 output[offset + offset2] = input[offset + offset2];
3125 memcpy(output, input, 3*width);
3126 memcpy(output + 3 * width * (height - 1), input + 3 * width * (height - 1), 3 * width);
3129 const unsigned int offset2 = 3 * (width - 1);
3130 for (
int y = 1;
y < height - 1;
y++, offset += 3 *
width)
3133 output[offset + 1] = input[offset + 1];
3134 output[offset + 2] = input[offset + 2];
3135 output[offset + offset2] = input[offset + offset2];
3136 output[offset + offset2 + 1] = input[offset + offset2 + 1];
3137 output[offset + offset2 + 2] = input[offset + offset2 + 2];
3148 printf(
"error: input and output images do not match for ImageProcessor::CopyFrame\n");
3153 unsigned char *output = pOutputImage->
pixels;
3161 memcpy(&output[1], &input[width + 1], width-2);
3162 memcpy(&output[width*(height-1) + 1], &input[width*(height-2) + 1], width-2);
3165 output[0] = input[width + 1];
3166 output[width - 1] = input[2*width - 2];
3167 output[width*(height-1)] = input[width*(height-2) + 1];
3168 output[width*height - 1] = input[width*height - 2];
3172 const unsigned int offset2 = width-1;
3173 for (
int y = 1;
y < height-1;
y++, offset +=
width)
3175 output[
offset] = input[offset+1];
3176 output[offset + offset2] = input[offset + offset2 - 1];
3182 memcpy(&output[3], &input[3*(width + 1)], 3*(width-2));
3183 memcpy(&output[3*(width*(height-1) + 1)], &input[3*(width*(height-2) + 1)], 3*(width-2));
3186 output[0] = input[3*(width + 1)];
3187 output[1] = input[3*(width + 1) + 1];
3188 output[2] = input[3*(width + 1) + 2];
3189 output[3*(width - 1)] = input[3*(2*width - 2)];
3190 output[3*(width - 1) + 1] = input[3*(2*width - 2) + 1];
3191 output[3*(width - 1) + 2] = input[3*(2*width - 2) + 2];
3192 output[3*(width*(height-1))] = input[3*(width*(height-2) + 1)];
3193 output[3*(width*(height-1)) + 1] = input[3*(width*(height-2) + 1) + 1];
3194 output[3*(width*(height-1)) + 2] = input[3*(width*(height-2) + 1) + 2];
3195 output[3*(width*height - 1)] = input[3*(width*(height-1) - 2)];
3196 output[3*(width*height - 1) + 1] = input[3*(width*(height-1) - 2) + 1];
3197 output[3*(width*height - 1) + 2] = input[3*(width*(height-1) - 2) + 2];
3201 const unsigned int offset2 = 3*(width-1);
3202 for (
int y = 1;
y < height-1;
y++, offset += 3*
width)
3204 output[
offset] = input[offset + 3];
3205 output[offset + 1] = input[offset + 3 + 1];
3206 output[offset + 2] = input[offset + 3 + 2];
3207 output[offset + offset2] = input[offset + offset2 - 3];
3208 output[offset + offset2 + 1] = input[offset + offset2 - 3 + 1];
3209 output[offset + offset2 + 2] = input[offset + offset2 - 3 + 2];
3217 bool ImageProcessor::ApplyHomography(
const CByteImage *pInputImage,
CByteImage *pOutputImage,
float a1,
float a2,
float a3,
float a4,
float a5,
float a6,
float a7,
float a8,
bool bInterpolation)
3219 const Mat3d A = { a1, a2, a3, a4, a5, a6, a7, a8, 1.0f };
3225 if (pInputImage->
type != pOutputImage->
type)
3227 printf(
"error: input and output image do not match in ImageProcessor::ApplyHomography\n");
3231 const float a1 = A.
r1;
3232 const float a2 = A.
r2;
3233 const float a3 = A.
r3;
3234 const float a4 = A.
r4;
3235 const float a5 = A.
r5;
3236 const float a6 = A.
r6;
3237 const float a7 = A.
r7;
3238 const float a8 = A.
r8;
3239 const float a9 = A.
r9;
3244 pSaveOutputImage = pOutputImage;
3250 const int output_width = pOutputImage->
width;
3251 const int output_height = pOutputImage->
height;
3253 unsigned char *output = pOutputImage->
pixels;
3260 for (
int v = 0,
offset = 0;
v < output_height;
v++)
3262 for (
int u = 0; u < output_width; u++,
offset++)
3264 const float u_ = (a1 * u + a2 *
v + a3) / (a7 * u + a8 *
v + a9);
3265 const float v_ = (a4 * u + a5 *
v + a6) / (a7 * u + a8 *
v + a9);
3267 const int u1 = int(floor(u_));
3268 const int v1 = int(floor(v_));
3269 const int u2 = u1 + 1;
3270 const int v2 = v1 + 1;
3272 unsigned char f00 = 0, f10 = 0, f01 = 0, f11 = 0;
3274 const bool v1_ok = v1 >= 0 && v1 <
height;
3275 const bool v2_ok = v2 >= 0 && v2 <
height;
3277 if (u1 >= 0 && u1 < width)
3280 f00 = input[v1 * width +
u1];
3283 f01 = input[v2 * width +
u1];
3286 if (u2 >= 0 && u2 < width)
3289 f10 = input[v1 * width +
u2];
3292 f11 = input[v2 * width +
u2];
3295 const float x = u_ -
u1;
3296 const float y = v_ -
v1;
3298 output[
offset] = (
unsigned char) (f00 * (1 - x) * (1 -
y) + f10 * x * (1 - y) + f01 * (1 -
x) * y + f11 * x * y + 0.5f);
3308 const float u_ = (a1 * u + a2 *
v + a3) / (a7 * u + a8 *
v + a9);
3309 const float v_ = (a4 * u + a5 *
v + a6) / (a7 * u + a8 *
v + a9);
3311 const int u1 = int(floor(u_));
3312 const int v1 = int(floor(v_));
3313 const int u2 = u1 + 1;
3314 const int v2 = v1 + 1;
3316 unsigned char f00_r = 0, f00_g = 0, f00_b = 0;
3317 unsigned char f10_r = 0, f10_g = 0, f10_b = 0;
3318 unsigned char f01_r = 0, f01_g = 0, f01_b = 0;
3319 unsigned char f11_r = 0, f11_g = 0, f11_b = 0;
3321 const bool v1_ok = v1 >= 0 && v1 <
height;
3322 const bool v2_ok = v2 >= 0 && v2 <
height;
3324 if (u1 >= 0 && u1 < width)
3328 const int x = 3 * (v1 * width +
u1);
3330 f00_g = input[x + 1];
3331 f00_b = input[x + 2];
3336 const int x = 3 * (v2 * width +
u1);
3338 f01_g = input[x + 1];
3339 f01_b = input[x + 2];
3343 if (u2 >= 0 && u2 < width)
3347 const int x = 3 * (v1 * width +
u2);
3349 f10_g = input[x + 1];
3350 f10_b = input[x + 2];
3355 const int x = 3 * (v2 * width +
u2);
3357 f11_g = input[x + 1];
3358 f11_b = input[x + 2];
3362 const float x = u_ -
u1;
3363 const float y = v_ -
v1;
3365 output[
offset ] = (
unsigned char) (f00_r * (1 - x) * (1 -
y) + f10_r * x * (1 - y) + f01_r * (1 -
x) * y + f11_r * x * y + 0.5f);
3366 output[offset + 1] = (
unsigned char) (f00_g * (1 - x) * (1 -
y) + f10_g * x * (1 - y) + f01_g * (1 -
x) * y + f11_g * x * y + 0.5f);
3367 output[offset + 2] = (
unsigned char) (f00_b * (1 - x) * (1 -
y) + f10_b * x * (1 - y) + f01_b * (1 -
x) * y + f11_b * x * y + 0.5f);
3376 for (
int v = 0,
offset = 0;
v < output_height;
v++)
3378 for (
int u = 0; u < output_width; u++,
offset++)
3380 const int u_ = (int) ((a1 * u + a2 *
v + a3) / (a7 * u + a8 *
v + 1.0f) + 0.5f);
3381 const int v_ = (int) ((a4 * u + a5 *
v + a6) / (a7 * u + a8 *
v + 1.0f) + 0.5f);
3383 if (u_ < 0 || u_ >= width || v_ < 0 || v_ >= height)
3386 output[
offset] = input[v_ * width + u_];
3392 for (
int v = 0,
offset = 0;
v < output_height;
v++)
3394 for (
int u = 0; u < output_width; u++,
offset += 3)
3396 const int u_ = (int) ((a1 * u + a2 *
v + a3) / (a7 * u + a8 *
v + 1.0f) + 0.5f);
3397 const int v_ = (int) ((a4 * u + a5 *
v + a6) / (a7 * u + a8 *
v + 1.0f) + 0.5f);
3399 if (u_ < 0 || u_ >= width || v_ < 0 || v_ >= height)
3400 output[
offset] = output[offset + 1] = output[offset + 2] = 0;
3403 const int offset2 = 3 * (v_ * width + u_);
3404 output[
offset] = input[offset2];
3405 output[offset + 1] = input[offset2 + 1];
3406 output[offset + 2] = input[offset2 + 2];
3413 if (pSaveOutputImage)
3415 CopyImage(pOutputImage, pSaveOutputImage);
3416 delete pOutputImage;
3426 printf(
"error: input and output image do not match in ImageProcessor::Resize\n");
3438 const int output_width = pOutputImage->
width;
3439 const int output_height = pOutputImage->
height;
3440 unsigned char *output = pOutputImage->
pixels;
3442 const int input_width = pInputImage->
width;
3443 const int input_height = pInputImage->
height;
3446 const int start_x = pROI ? pROI->
min_x : 0;
3447 const int start_y = pROI ? pROI->
min_y : 0;
3454 if (pROI->
min_x < 0 || pROI->
min_y < 0 || pROI->
max_x >= input_width || pROI->
max_y >= input_height)
3456 printf(
"error: provided ROI in ImageProcessor::Resize exceeds input image boundaries\n");
3461 if (width > output_width && width % output_width == 0 &&
3462 height > output_height && height % output_height == 0)
3466 const int a1 = width / output_width;
3467 const int a4 = height / output_height;
3468 const int delta = a4 * input_width -
width;
3470 for (
int v = 0,
offset = 0, offset_ = start_y * input_width + start_x;
v < output_height;
v++, offset_ += delta)
3472 for (
int u = 0; u < output_width; u++,
offset++, offset_ += a1)
3473 output[offset] = input[offset_];
3478 const int a1 = 3 * (width / output_width);
3479 const int a4 = height / output_height;
3480 const int delta = 3 * (a4 * input_width -
width);
3482 for (
int v = 0,
offset = 0, offset_ = 3 * (start_y * input_width + start_x);
v < output_height;
v++, offset_ += delta)
3484 for (
int u = 0; u < output_width; u++,
offset += 3, offset_ += a1)
3486 output[
offset] = input[offset_];
3487 output[offset + 1] = input[offset_ + 1];
3488 output[offset + 2] = input[offset_ + 2];
3496 const float a1 = float(width) / output_width;
3497 const float a4 = float(height) / output_height;
3499 int *pXOffsets = 0, *pYOffsets = 0;
3500 int *pXCoordinates = 0, *pYCoordinates = 0;
3502 const int min_width =
MY_MIN(width, output_width);
3503 const int min_height =
MY_MIN(height, output_height);
3508 pXOffsets =
new int[output_width];
3509 pYOffsets =
new int[output_height];
3513 pXCoordinates =
new int[output_width];
3514 pYCoordinates =
new int[output_height];
3516 for (i = 0; i < output_width; i++)
3518 register int x = (i *
width) / output_width;
3520 if (start_x + x < input_width - 1)
3522 pXOffsets[i] = start_x +
x;
3523 pXCoordinates[i] = int((i * a1 - x) * 1024);
3527 pXOffsets[i] = input_width - 2;
3528 pXCoordinates[i] = 1024;
3532 for (i = 0; i < output_height; i++)
3534 register int y = (i *
height) / output_height;
3536 if (start_y + y < input_height - 1)
3538 pYOffsets[i] = input_width * (start_y +
y);
3539 pYCoordinates[i] = int((i * a4 - y) * 1024);
3543 pYOffsets[i] = input_width * (input_height - 2);
3544 pYCoordinates[i] = 1024;
3550 for (i = 0; i < output_width; i++)
3551 pXOffsets[i] = start_x + (((i * width) << 1) + min_width - 1) / (output_width << 1);
3553 for (i = 0; i < output_height; i++)
3554 pYOffsets[i] = input_width * (start_y + (((i * height) << 1) + min_height - 1) / (output_height << 1));
3559 pXOffsets =
new int[3 * output_width];
3560 pYOffsets =
new int[output_height];
3566 pXCoordinates =
new int[3 * output_width];
3567 pYCoordinates =
new int[output_height];
3569 for (i = 0; i < output_width; i++, offset += 3)
3571 register int x = (i *
width) / output_width;
3573 if (start_x + x < input_width - 1)
3575 pXOffsets[
offset] = 3 * (start_x +
x);
3576 pXCoordinates[
offset] = int((i * a1 - x) * 1024);
3580 pXOffsets[
offset] = 3 * (input_width - 2);
3581 pXCoordinates[
offset] = 1024;
3585 for (i = 0; i < output_height; i++)
3587 register int y = (i *
height) / output_height;
3589 if (start_y + y < input_height - 1)
3591 pYOffsets[i] = 3 * input_width * (start_y +
y);
3592 pYCoordinates[i] = int((i * a4 - y) * 1024);
3596 pYOffsets[i] = 3 * input_width * (input_height - 2);
3597 pYCoordinates[i] = 1024;
3603 for (i = 0; i < output_width; i++, offset += 3)
3604 pXOffsets[offset] = 3 * (start_x + (((i * width) << 1) + min_width - 1) / (output_width << 1));
3606 for (i = 0; i < output_height; i++)
3607 pYOffsets[i] = 3 * input_width * (start_y + (((i * height) << 1) + min_height - 1) / (output_height << 1));
3615 const int last_u =
MY_MAX(0, output_width - output_width % 4);
3617 for (
int v = 0;
v < output_height;
v++)
3619 const unsigned char *input_helper = input + pYOffsets[
v];
3620 const int y = pYCoordinates[
v];
3623 for (u = 0; u < last_u; u += 4)
3628 offset = pXOffsets[u];
3629 x = pXCoordinates[u];
3630 output[u] = (
unsigned char) (
3631 ((input_helper[offset] * (1024 - x) * (1024 - y)) +
3632 (input_helper[offset + 1] * x * (1024 - y)) +
3633 (input_helper[offset + input_width] * (1024 - x) * y) +
3634 (input_helper[offset + input_width + 1] * x * y)) >> 20
3637 offset = pXOffsets[u + 1];
3638 x = pXCoordinates[u + 1];
3639 output[u + 1] = (
unsigned char) (
3640 ((input_helper[offset] * (1024 - x) * (1024 - y)) +
3641 (input_helper[offset + 1] * x * (1024 -
y)) +
3642 (input_helper[offset + input_width] * (1024 -
x) * y) +
3643 (input_helper[offset + input_width + 1] * x *
y)) >> 20
3646 offset = pXOffsets[u + 2];
3647 x = pXCoordinates[u + 2];
3648 output[u + 2] = (
unsigned char) (
3649 ((input_helper[offset] * (1024 - x) * (1024 -
y)) +
3650 (input_helper[offset + 1] * x * (1024 -
y)) +
3651 (input_helper[offset + input_width] * (1024 -
x) * y) +
3652 (input_helper[offset + input_width + 1] * x *
y)) >> 20
3655 offset = pXOffsets[u + 3];
3656 x = pXCoordinates[u + 3];
3657 output[u + 3] = (
unsigned char) (
3658 ((input_helper[offset] * (1024 - x) * (1024 -
y)) +
3659 (input_helper[offset + 1] * x * (1024 -
y)) +
3660 (input_helper[offset + input_width] * (1024 -
x) * y) +
3661 (input_helper[offset + input_width + 1] * x *
y)) >> 20
3665 for (u = last_u; u < output_width; u++)
3667 const int offset = pXOffsets[u];
3668 const int x = pXCoordinates[u];
3669 output[u] = (
unsigned char) (
3670 ((input_helper[offset] * (1024 - x) * (1024 -
y)) +
3671 (input_helper[offset + 1] * x * (1024 -
y)) +
3672 (input_helper[offset + input_width] * (1024 -
x) * y) +
3673 (input_helper[offset + input_width + 1] * x *
y)) >> 20
3677 output += output_width;
3682 const int output_width3 = 3 * output_width;
3683 const int input_width3 = 3 * input_width;
3685 for (
int v = 0;
v < output_height;
v++)
3687 const unsigned char *input_helper = input + pYOffsets[
v];
3688 const int y = pYCoordinates[
v];
3690 for (
int u = 0; u < output_width3; u += 3)
3692 const int x = pXCoordinates[u];
3693 const int f00 = (1024 -
x) * (1024 - y);
3694 const int f10 = x * (1024 -
y);
3695 const int f01 = (1024 -
x) * y;
3696 const int f11 = x *
y;
3700 offset = pXOffsets[u];
3701 output[u] = (
unsigned char) (
3702 ((input_helper[offset] * f00) +
3703 (input_helper[offset + 3] * f10) +
3704 (input_helper[offset + input_width3] * f01) +
3705 (input_helper[offset + input_width3 + 3] * f11)) >> 20
3709 output[u + 1] = (
unsigned char) (
3710 ((input_helper[offset] * f00) +
3711 (input_helper[offset + 3] * f10) +
3712 (input_helper[offset + input_width3] * f01) +
3713 (input_helper[offset + input_width3 + 3] * f11)) >> 20
3717 output[u + 2] = (
unsigned char) (
3718 ((input_helper[offset] * f00) +
3719 (input_helper[offset + 3] * f10) +
3720 (input_helper[offset + input_width3] * f01) +
3721 (input_helper[offset + input_width3 + 3] * f11)) >> 20
3725 output += output_width3;
3733 const int last_u =
MY_MAX(0, output_width - output_width % 4);
3735 for (
int v = 0;
v < output_height;
v++)
3737 const unsigned char *input_helper = input + pYOffsets[
v];
3740 for (u = 0; u < last_u; u += 4)
3742 output[u] = input_helper[pXOffsets[u]];
3743 output[u + 1] = input_helper[pXOffsets[u + 1]];
3744 output[u + 2] = input_helper[pXOffsets[u + 2]];
3745 output[u + 3] = input_helper[pXOffsets[u + 3]];
3748 for (u = last_u; u < output_width; u++)
3749 output[u] = input_helper[pXOffsets[u]];
3751 output += output_width;
3756 const int output_width3 = 3 * output_width;
3757 const int last_u = 3 *
MY_MAX(0, output_width - output_width % 4);
3759 for (
int v = 0;
v < output_height;
v++)
3761 const unsigned char *input_helper = input + pYOffsets[
v];
3764 for (u = 0; u < last_u; u += 12)
3766 register int input_offset;
3768 input_offset = pXOffsets[u];
3769 output[u] = input_helper[input_offset];
3770 output[u + 1] = input_helper[input_offset + 1];
3771 output[u + 2] = input_helper[input_offset + 2];
3773 input_offset = pXOffsets[u + 3];
3774 output[u + 3] = input_helper[input_offset];
3775 output[u + 4] = input_helper[input_offset + 1];
3776 output[u + 5] = input_helper[input_offset + 2];
3778 input_offset = pXOffsets[u + 6];
3779 output[u + 6] = input_helper[input_offset];
3780 output[u + 7] = input_helper[input_offset + 1];
3781 output[u + 8] = input_helper[input_offset + 2];
3783 input_offset = pXOffsets[u + 9];
3784 output[u + 9] = input_helper[input_offset];
3785 output[u + 10] = input_helper[input_offset + 1];
3786 output[u + 11] = input_helper[input_offset + 2];
3789 for (u = last_u; u < output_width3; u += 3)
3791 register int input_offset = pXOffsets[u];
3792 output[u] = input_helper[input_offset];
3793 output[u + 1] = input_helper[input_offset + 1];
3794 output[u + 2] = input_helper[input_offset + 2];
3797 output += output_width3;
3802 delete [] pXOffsets;
3803 delete [] pYOffsets;
3807 delete [] pXCoordinates;
3808 delete [] pYCoordinates;
3817 const float cos_theta = cosf(theta);
3818 const float sin_theta = sinf(theta);
3821 cos_theta, -sin_theta, mx * (1 - cos_theta) + my * sin_theta,
3822 sin_theta, cos_theta, my * (1 - cos_theta) - mx * sin_theta,
3833 printf(
"error: input and output image do not match for ImageProcessor::Amplify\n");
3839 unsigned char *output = pOutputImage->
pixels;
3841 for (
int i = 0; i < nBytes; i++)
3843 const int v = int(fFactor * input[i] + 0.5f);
3858 printf(
"error: input and output image do not match for ImageProcessor::CalculateSaturationImage\n");
3862 const int nPixels = pInputImage->
width * pInputImage->
height;
3863 unsigned char *output = pOutputImage->
pixels;
3869 for (
int i = 0,
offset = 0; i < nPixels; i++)
3872 const int g = input[
offset + 1];
3873 const int b = input[
offset + 2];
3882 const unsigned char *input_r = pInputImage->
pixels;
3883 const unsigned char *input_g = input_r + nPixels;
3884 const unsigned char *input_b = input_g + nPixels;
3886 for (
int i = 0; i < nPixels; i++)
3888 const int r = input_r[i];
3889 const int g = input_g[i];
3890 const int b = input_b[i];
3908 printf(
"error: input and output image do not match for ImageProcessor::ThresholdBinarize\n");
3912 const int nPixels = pInputImage->
width * pInputImage->
height;
3914 unsigned char *output = pOutputImage->
pixels;
3916 for (
int i = 0; i < nPixels; i++)
3917 output[i] = input[i] >= nThreshold ? 255 : 0;
3931 printf(
"error: input and output image do not match for ImageProcessor::ThresholdBinarize\n");
3935 const int nPixels = pInputImage->
width * pInputImage->
height;
3937 unsigned char *output = pOutputImage->
pixels;
3939 for (
int i = 0; i < nPixels; i++)
3940 output[i] = input[i] >= nMinThreshold && input[i] <= nMaxThreshold ? 255 : 0;
3951 printf(
"error: input and output matrix do not match for ImageProcessor::ThresholdBinarize\n");
3955 const int n = pInputMatrix->
columns * pInputMatrix->
rows;
3956 const float *
input = pInputMatrix->
data;
3957 float *output = pOutputMatrix->
data;
3959 for (
int i = 0; i <
n; i++)
3960 output[i] = input[i] >= fThreshold ? 255.0f : 0;
3972 printf(
"error: input and output image do not match for ImageProcessor::ThresholdBinarizeInverse\n");
3977 unsigned char *output = pOutputImage->
pixels;
3978 const int nPixels = pInputImage->
width * pInputImage->
height;
3980 for (
int i = 0; i < nPixels; i++)
3981 output[i] = input[i] <= nThreshold ? 255 : 0;
3995 printf(
"error: input and output image do not match for ImageProcessor::ThresholdFilter\n");
3999 const int nPixels = pInputImage->
width * pInputImage->
height;
4001 unsigned char *output = pOutputImage->
pixels;
4003 for (
int i = 0; i < nPixels; i++)
4004 output[i] = input[i] >= nThreshold ? input[i] : 0;
4018 printf(
"error: input and output image do not match for ImageProcessor::ThresholdFilterInverse\n");
4023 unsigned char *output = pOutputImage->
pixels;
4024 const int nPixels = pInputImage->
width * pInputImage->
height;
4026 for (
int i = 0; i < nPixels; i++)
4027 output[i] = input[i] <= nThreshold ? input[i] : 0;
4040 printf(
"error: input and output image do not match for ImageProcessor::FilterRGB\n");
4045 unsigned char *output = pOutputImage->
pixels;
4046 const int nPixels = pInputImage->
width * pInputImage->
height;
4049 for (
int i = 0; i < nPixels; i++, offset += 3)
4051 Vec3d rgb = { input[
offset], input[offset + 1], input[offset + 2] };
4063 printf(
"error: input and output image do not match for ImageProcessor::FilterHSV\n");
4067 int min_hue = (int) hue - (
int) tol_hue;
4068 int max_hue = (int) hue + (
int) tol_hue;
4082 return FilterHSV2(pInputImage, pOutputImage, (
unsigned char) min_hue, (
unsigned char) max_hue, min_sat, max_sat, min_v, max_v, pROI);
4092 printf(
"error: input and output image do not match for ImageProcessor::FilterHSV2\n");
4098 const unsigned char *input_h = pInputImage->
pixels;
4099 const unsigned char *input_s = pInputImage->
pixels + 1;
4100 const unsigned char *input_v = pInputImage->
pixels + 2;
4101 unsigned char *output = pOutputImage->
pixels;
4108 int min_x = pROI->
min_x;
4109 int max_x = pROI->
max_x;
4110 int min_y = pROI->
min_y;
4111 int max_y = pROI->
max_y;
4113 if (min_x < 0) min_x = 0;
4114 if (min_x > width - 1) min_x = width - 1;
4115 if (max_x < 0) max_x = 0;
4116 if (max_x > width - 1) max_x = width - 1;
4117 if (min_y < 0) min_y = 0;
4118 if (min_y > height - 1) min_y = height - 1;
4119 if (max_y < 0) max_y = 0;
4120 if (max_y > height - 1) max_y = height - 1;
4122 const int diff = width - (max_x - min_x + 1);
4123 const int diff_rgb = 3 * diff;
4125 if (max_hue >= min_hue)
4127 for (
int y = min_y,
offset = min_y * width + min_x, offset_rgb = 3 * (min_y * width + min_x);
y <= max_y;
y++,
offset += diff, offset_rgb += diff_rgb)
4128 for (
int x = min_x;
x <= max_x;
x++, offset++, offset_rgb += 3)
4129 output[offset] = (input_s[offset_rgb] <= max_sat && input_s[offset_rgb] >= min_sat && input_h[offset_rgb] >= min_hue && input_h[offset_rgb] <= max_hue && input_v[offset_rgb] >= min_v && input_v[offset_rgb] <= max_v) * 255;
4133 for (
int y = min_y,
offset = min_y * width + min_x, offset_rgb = 3 * (min_y * width + min_x);
y <= max_y;
y++,
offset += diff, offset_rgb += diff_rgb)
4134 for (
int x = min_x;
x <= max_x;
x++, offset++, offset_rgb += 3)
4135 output[offset] = (input_s[offset_rgb] <= max_sat && input_s[offset_rgb] >= min_sat && (input_h[offset_rgb] >= min_hue || input_h[offset_rgb] <= max_hue) && input_v[offset_rgb] >= min_v && input_v[offset_rgb] <= max_v) * 255;
4140 const int nPixels = pInputImage->
width * pInputImage->
height;
4142 if (max_hue >= min_hue)
4144 for (
int i = 0,
offset = 0; i < nPixels; i++,
offset += 3)
4145 output[i] = (input_s[offset] <= max_sat && input_s[offset] >= min_sat && input_h[offset] >= min_hue && input_h[offset] <= max_hue && input_v[offset] >= min_v && input_v[offset] <= max_v) * 255;
4149 for (
int i = 0,
offset = 0; i < nPixels; i++,
offset += 3)
4150 output[i] = (input_s[offset] <= max_sat && input_s[offset] >= min_sat && (input_h[offset] >= min_hue || input_h[offset] <= max_hue) && input_v[
offset] >= min_v && input_v[
offset] <= max_v) * 255;
4158 const int nPixels = width *
height;
4160 const unsigned char *input_h = pInputImage->
pixels;
4161 const unsigned char *input_s = input_h + nPixels;
4162 const unsigned char *input_v = input_s + nPixels;
4163 unsigned char *output = pOutputImage->
pixels;
4167 int min_x = pROI->
min_x;
4168 int max_x = pROI->
max_x;
4169 int min_y = pROI->
min_y;
4170 int max_y = pROI->
max_y;
4172 if (min_x < 0) min_x = 0;
4173 if (min_x > width - 1) min_x = width - 1;
4174 if (max_x < 0) max_x = 0;
4175 if (max_x > width - 1) max_x = width - 1;
4176 if (min_y < 0) min_y = 0;
4177 if (min_y > height - 1) min_y = height - 1;
4178 if (max_y < 0) max_y = 0;
4179 if (max_y > height - 1) max_y = height - 1;
4181 const int diff = width - (max_x - min_x + 1);
4183 if (max_hue >= min_hue)
4185 for (
int y = min_y,
offset = min_y * width + min_x;
y <= max_y;
y++,
offset += diff)
4186 for (
int x = min_x;
x <= max_x;
x++, offset++)
4187 output[offset] = (input_s[offset] <= max_sat && input_s[offset] >= min_sat && input_h[offset] >= min_hue && input_h[offset] <= max_hue && input_v[offset] >= min_v && input_v[offset] <= max_v) * 255;
4191 for (
int y = min_y,
offset = min_y * width + min_x;
y <= max_y;
y++,
offset += diff)
4192 for (
int x = min_x;
x <= max_x;
x++, offset++)
4193 output[offset] = (input_s[offset] <= max_sat && input_s[offset] >= min_sat && (input_h[offset] >= min_hue || input_h[offset] <= max_hue) && input_v[
offset] >= min_v && input_v[
offset] <= max_v) * 255;
4198 if (max_hue >= min_hue)
4200 for (
int i = 0; i < nPixels; i++)
4201 output[i] = (input_s[i] <= max_sat && input_s[i] >= min_sat && input_h[i] >= min_hue && input_h[i] <= max_hue && input_v[i] >= min_v && input_v[i] <= max_v) * 255;
4205 for (
int i = 0; i < nPixels; i++)
4206 output[i] = (input_s[i] <= max_sat && input_s[i] >= min_sat && (input_h[i] >= min_hue || input_h[i] <= max_hue) && input_v[i] >= min_v && input_v[i] <= max_v) * 255;
4225 bRet =
FilterHSV(pInputImage, pOutputImage, pParams[0], pParams[1], pParams[2], pParams[3], pParams[4], pParams[5]);
4231 bRet =
FilterHSV(pImage, pOutputImage, pParams[0], pParams[1], pParams[2], pParams[3], pParams[4], pParams[5]);
4244 printf(
"error: input and output image do not match for ImageProcessor::Rotate180Degrees\n");
4251 pSaveOutputImage = pOutputImage;
4258 unsigned char *output = pOutputImage->
pixels;
4262 for (
int i = 0; i < nBytes; i++)
4263 output[i] = input[nLastPixel - i];
4267 for (
int i = 0; i < nBytes; i += 3)
4269 output[i + 2] = input[nLastPixel - i + 2];
4270 output[i + 1] = input[nLastPixel - i + 1];
4271 output[i] = input[nLastPixel - i];
4275 if (pSaveOutputImage)
4277 CopyImage(pOutputImage, pSaveOutputImage);
4278 delete pOutputImage;
4289 int sp = 0, nPixels = 0;
4296 const int offset = stack[sp];
4298 if (pixels[offset - width] == 255)
4300 pixels[offset -
width] = 254;
4301 stack[sp++] = offset -
width;
4304 if (pixels[offset - 1] == 255)
4306 pixels[offset - 1] = 254;
4307 stack[sp++] = offset - 1;
4310 if (pixels[offset + 1] == 255)
4312 pixels[offset + 1] = 254;
4313 stack[sp++] = offset + 1;
4316 if (pixels[offset + width] == 255)
4318 pixels[offset +
width] = 254;
4319 stack[sp++] = offset +
width;
4322 region[nPixels++] =
offset;
4325 if ((nMinimumPointsPerRegion > 0 && nPixels < nMinimumPointsPerRegion) || (nMaximumPointsPerRegion > 0 && nPixels > nMaximumPointsPerRegion))
4330 if (bCalculateBoundingBox)
4332 const int x = offset %
width;
4333 const int y = offset /
width;
4334 int min_x =
x, max_x =
x, min_y =
y, max_y =
y;
4336 for (
int i = 0; i < nPixels; i++)
4338 const int offset = region[i];
4339 const int x = offset %
width;
4340 const int y = offset /
width;
4358 resultRegion.
min_x = min_x;
4359 resultRegion.
min_y = min_y;
4360 resultRegion.
max_x = max_x;
4361 resultRegion.
max_y = max_y;
4362 resultRegion.
ratio = float(max_x - min_x + 1) / float(max_y - min_y + 1);
4366 for (
int i = 0; i < nPixels; i++)
4368 const int offset = region[i];
4370 cx += offset %
width;
4371 cy += offset /
width;
4374 resultRegion.
min_x = -1;
4375 resultRegion.
min_y = -1;
4376 resultRegion.
max_x = -1;
4377 resultRegion.
max_y = -1;
4378 resultRegion.
ratio = 0.0f;
4382 resultRegion.
nPixels = nPixels;
4383 resultRegion.
centroid.
x = float(cx) / nPixels;
4384 resultRegion.
centroid.
y = float(cy) / nPixels;
4393 printf(
"error: input image should be grayscale for ImageProcessor::RegionGrowing\n");
4402 printf(
"error: x/y is not within bounds of image in ImageProcessor::RegionGrowing\n");
4409 const int temp_width = pTempImage->
width;
4410 const int temp_height = pTempImage->
height;
4412 unsigned char *temp = pTempImage->
pixels;
4415 unsigned char *temp_helper = temp + temp_width + 1;
4417 for (
int i = 0; i < pImage->
height; i++)
4418 memcpy(temp_helper + i * temp_width, pImage->
pixels + i * width, width);
4424 const int nPixels = temp_width * temp_height;
4426 int *pStack =
new int[nPixels];
4427 int *pRegionPixels =
new int[nPixels];
4430 const int nRegionPixels =
_RegionGrowing(temp, temp_width, (y + 1) * temp_width + (x + 1), pStack, pRegionPixels, resultRegion, nMinimumPointsPerRegion, nMaximumPointsPerRegion, bCalculateBoundingBox);
4434 delete [] resultRegion.
pPixels;
4438 if (nRegionPixels > 0)
4442 resultRegion.
pPixels =
new int[nRegionPixels];
4444 for (
int j = 0; j < nRegionPixels; j++)
4446 const int x = pRegionPixels[j] % temp_width;
4447 const int y = pRegionPixels[j] / temp_width;
4449 resultRegion.
pPixels[j] = (y - 1) * width + x - 1;
4457 resultRegion.
min_x -= 1;
4458 resultRegion.
min_y -= 1;
4459 resultRegion.
max_x -= 1;
4460 resultRegion.
max_y -= 1;
4468 delete [] pRegionPixels;
4470 return nRegionPixels;
4480 printf(
"error: input image should be grayscale for ImageProcessor::FindRegions\n");
4490 const int temp_width = pTempImage->
width;
4491 const int temp_height = pTempImage->
height;
4493 unsigned char *temp = pTempImage->
pixels;
4496 unsigned char *temp_helper = temp + temp_width + 1;
4498 for (
int y = 0;
y < pImage->
height;
y++)
4499 memcpy(temp_helper +
y * temp_width, pImage->
pixels +
y * width, width);
4505 const int nPixels = temp_width * temp_height;
4507 int *pStack =
new int[nPixels];
4508 int *pRegionPixels =
new int[nPixels];
4511 for (
int i = 0; i < nPixels; i++)
4518 const int nRegionPixels =
_RegionGrowing(temp, temp_width, i, pStack, pRegionPixels, region, nMinimumPointsPerRegion, nMaximumPointsPerRegion, bCalculateBoundingBox);
4520 if (nRegionPixels > 0)
4523 regionList.push_back(region);
4527 MyRegion &addedEntry = regionList.back();
4533 addedEntry.
min_x -= 1;
4534 addedEntry.
min_y -= 1;
4535 addedEntry.
max_x -= 1;
4536 addedEntry.
max_y -= 1;
4540 addedEntry.
pPixels =
new int[nRegionPixels];
4542 for (
int j = 0; j < nRegionPixels; j++)
4544 const int x = pRegionPixels[j] % temp_width;
4545 const int y = pRegionPixels[j] / temp_width;
4547 addedEntry.
pPixels[j] = (y - 1) * width + x - 1;
4559 delete [] pRegionPixels;
4571 printf(
"error: input image should be grayscale for ImageProcessor::FindRegions\n");
4581 const int temp_width = pTempImage->
width;
4582 const int temp_height = pTempImage->
height;
4584 unsigned char *temp = pTempImage->
pixels;
4587 unsigned char *temp_helper = temp + temp_width + 1;
4589 for (
int y = 0;
y < pImage->
height;
y++)
4590 memcpy(temp_helper +
y * temp_width, pImage->
pixels +
y * width, width);
4596 const int nPixels = temp_width * temp_height;
4598 int *pStack =
new int[nPixels];
4599 int *pRegionPixels =
new int[nPixels];
4602 for (
int i = 0; i < nPixels; i++)
4609 const int nRegionPixels =
_RegionGrowing(temp, temp_width, i, pStack, pRegionPixels, region, nMinimumPointsPerRegion, nMaximumPointsPerRegion, bCalculateBoundingBox);
4611 if (nRegionPixels > 0)
4624 addedEntry.
min_x -= 1;
4625 addedEntry.
min_y -= 1;
4626 addedEntry.
max_x -= 1;
4627 addedEntry.
max_y -= 1;
4631 addedEntry.
pPixels =
new int[nRegionPixels];
4633 for (
int j = 0; j < nRegionPixels; j++)
4635 const int x = pRegionPixels[j] % temp_width;
4636 const int y = pRegionPixels[j] / temp_width;
4638 addedEntry.
pPixels[j] = (y - 1) * width + x - 1;
4650 delete [] pRegionPixels;
4663 printf(
"error: input and output image do not match for ImageProcessor::CalculateHSVImage\n");
4668 unsigned char *output = pOutputImage->
pixels;
4677 int min_x = pROI->
min_x;
4678 int max_x = pROI->
max_x;
4679 int min_y = pROI->
min_y;
4680 int max_y = pROI->
max_y;
4682 if (min_x < 0) min_x = 0;
4683 if (min_x > width - 1) min_x = width - 1;
4684 if (max_x < 0) max_x = 0;
4685 if (max_x > width - 1) max_x = width - 1;
4686 if (min_y < 0) min_y = 0;
4687 if (min_y > height - 1) min_y = height - 1;
4688 if (max_y < 0) max_y = 0;
4689 if (max_y > height - 1) max_y = height - 1;
4691 const int diff = 3 * (width - (max_x - min_x + 1));
4693 for (
int y = min_y,
offset = 3 * (min_y * width + min_x);
y <= max_y;
y++,
offset += diff)
4695 for (
int x = min_x;
x <= max_x;
x++, offset += 3)
4698 const int g = input[offset + 1];
4699 const int b = input[offset + 2];
4703 const int delta = max - min;
4717 if (h >= 180) h -= 180;
4720 output[offset + 1] =
s;
4721 output[offset + 2] = max;
4730 const int nPixels = width *
height;
4732 const unsigned char *input_r =
input;
4733 const unsigned char *input_g = input_r + nPixels;
4734 const unsigned char *input_b = input_g + nPixels;
4735 unsigned char *output_r = output;
4736 unsigned char *output_g = output_r + nPixels;
4737 unsigned char *output_b = output_g + nPixels;
4739 int min_x = pROI->
min_x;
4740 int max_x = pROI->
max_x;
4741 int min_y = pROI->
min_y;
4742 int max_y = pROI->
max_y;
4744 if (min_x < 0) min_x = 0;
4745 if (min_x > width - 1) min_x = width - 1;
4746 if (max_x < 0) max_x = 0;
4747 if (max_x > width - 1) max_x = width - 1;
4748 if (min_y < 0) min_y = 0;
4749 if (min_y > height - 1) min_y = height - 1;
4750 if (max_y < 0) max_y = 0;
4751 if (max_y > height - 1) max_y = height - 1;
4753 const int diff = width - (max_x - min_x + 1);
4755 for (
int y = min_y,
offset = min_y * width + min_x;
y <= max_y;
y++,
offset += diff)
4757 for (
int x = min_x;
x <= max_x;
x++, offset++)
4759 const int r = input_r[
offset];
4760 const int g = input_g[
offset];
4761 const int b = input_b[
offset];
4765 const int delta = max - min;
4779 if (h >= 180) h -= 180;
4792 const int maxi = pInputImage->
width * pInputImage->
height * 3;
4794 for (
int i = 0; i < maxi; i += 3)
4796 const int r = input[i];
4797 const int g = input[i + 1];
4798 const int b = input[i + 2];
4802 const int delta = max - min;
4816 if (h >= 180) h -= 180;
4820 output[i + 2] = max;
4825 const int nPixels = pInputImage->
width * pInputImage->
height;
4827 const unsigned char *input_r =
input;
4828 const unsigned char *input_g = input_r + nPixels;
4829 const unsigned char *input_b = input_g + nPixels;
4830 unsigned char *output_r = output;
4831 unsigned char *output_g = output_r + nPixels;
4832 unsigned char *output_b = output_g + nPixels;
4834 for (
int i = 0; i < nPixels; i++)
4836 const int r = input_r[i];
4837 const int g = input_g[i];
4838 const int b = input_b[i];
4842 const int delta = max - min;
4856 if (h >= 180) h -= 180;
4875 printf(
"error: input image must be of type CByteImage::eGrayScale\n");
4883 const int m = 1 + 2 * (int(sqrtf(
float(width * width + height * height))) + 1);
4884 const int m2 = m / 2;
4885 const float m2f = float(m2) + 0.5f;
4887 const int nHoughPixels = n * m;
4893 short *houghspace = houghSpace.
pixels;
4906 for (
int t = 0;
t <
n;
t++)
4909 const int r_ = int(r + m2f);
4911 houghspace[
t * m + r_]++;
4917 resultLines.clear();
4920 for (
int nn = 0; nn < nLinesToExtract; nn++)
4922 int max = nMinHits - 1, best_i = -1;
4924 for (
int i = 0; i < nHoughPixels; i++)
4926 if (houghspace[i] > max)
4928 max = houghspace[i];
4935 const int t = best_i / m;
4936 const int r = best_i % m;
4940 for (
int j = -w; j <=
w; j++)
4942 for (
int k = -w; k <=
w; k++)
4944 const int r_ = r + j;
4953 if (r_ >= 0 && r_ < m)
4954 houghspace[t_ * m + r_] = 0;
4959 const int r_value = r - m2;
4961 const Vec2d g = { theta, float(r_value) };
4962 resultLines.push_back(g);
4964 if (pVisualizationImage)
4981 printf(
"error: rmin (%i) may not be greater than rmax (%i) for ImageProcessor::HoughTransformCircles\n", rmin, rmax);
4989 const int n = width + 2 * rmax;
4990 const int m = height + 2 * rmax;
4991 const int nHoughPixels = n * m * (rmax - rmin + 1);
4993 short *houghspace =
new short[nHoughPixels];
4996 memset(houghspace, 0, nHoughPixels *
sizeof(
short));
5002 const int mn = m *
n;
5003 short *helper = houghspace - rmin * mn + rmax * m + rmax;
5010 if (pixels[
offset] == 255)
5012 for (
int t = 0;
t < 180;
t++)
5014 for (
int r = rmin;
r <= rmax;
r++)
5024 const int base =
r * mn + um * m;
5025 helper[base + vm1]++;
5026 helper[base + vm2]++;
5033 resultCircles.clear();
5036 for (
int nn = 0; nn < nCirclesToExtract; nn++)
5038 int max = nMinHits - 1, best_i = -1;
5040 for (
int i = 0; i < nHoughPixels; i++)
5042 if (houghspace[i] > max)
5044 max = houghspace[i];
5051 int um = (best_i % mn) / m;
5052 int vm = (best_i % mn) % m;
5053 int r = best_i / mn;
5057 for (
int j = -w; j <=
w; j++)
5059 for (
int k = -w; k <=
w; k++)
5061 for (
int l = -w; l <=
w; l++)
5063 const int um_ = um + j;
5064 const int vm_ = vm + k;
5065 const int r_ = r + l;
5067 if (um_ >= 0 && um_ < n && vm >= 0 && vm < m && r_ >= 0 && r_ <= rmax - rmin)
5068 houghspace[r_ * mn + um_ * m + vm_] = 0;
5079 const Vec3d circle = { float(um), float(vm), float(r) };
5080 resultCircles.push_back(circle);
5082 if (pVisualizationImage)
5084 Vec2d center = { float(um), float(vm) };
5092 delete [] houghspace;
5100 resultLines.
Clear();
5105 HoughTransformLines(edgePoints, edgeDirections, width, height, nLinesToExtract, nMinHits, resultLines_, resultHits, pVisualizationImage);
5108 const int nResultLines = resultLines_.
GetSize();
5110 for (
int i = 0; i < nResultLines; i++)
5123 resultLines.
Clear();
5125 const int m = 1 + 2 * (int(sqrtf(
float(width * width + height * height))) + 1);
5126 const int m2 = m / 2;
5127 const float m2f = float(m2) + 0.5f;
5129 const int nHoughPixels = n * m;
5135 short *houghspace = houghSpace.
pixels;
5142 const int nEdgePoints = edgePoints.
GetSize();
5143 for (
int i = 0; i < nEdgePoints; i++)
5145 const Vec2d &point = edgePoints[i];
5146 const Vec2d &direction = edgeDirections[i];
5148 const float angle = atan2f(direction.
y, direction.
x) +
FLOAT_PI;
5151 const int t1 = t0 - 5;
5152 const int t2 = t0 + 5;
5154 for (
int t = t1;
t <= t2;
t++)
5157 const int r_ = int(r + m2f);
5159 houghspace[((
t + 360) % 360) * m + r_]++;
5163 resultLines.
Clear();
5167 for (
int nn = 0; nn < nLinesToExtract; nn++)
5169 short max = nMinHits - 1;
5172 for (
int i = 0; i < nHoughPixels; i++)
5174 if (houghspace[i] > max)
5176 max = houghspace[i];
5183 const int t = best_i / m;
5184 const int r = best_i % m;
5188 for (
int j = -w; j <=
w; j++)
5190 for (
int k = -w; k <=
w; k++)
5192 const int r_ = r + j;
5201 if (r_ >= 0 && r_ < m)
5202 houghspace[t_ * m + r_] = 0;
5207 const int r_value = r - m2;
5212 if (pVisualizationImage)
5223 bool ImageProcessor::HoughTransformCircles(
const CVec2dArray &edgePoints,
const CVec2dArray &edgeDirections,
int width,
int height,
int rmin,
int rmax,
int nCirclesToExtract,
int nMinHits,
CVec3dArray &resultCircles,
CIntArray &resultHits,
CByteImage *pVisualizationImage)
5226 resultCircles.
Clear();
5231 if (!
HoughTransformCircles(edgePoints, edgeDirections, width, height, rmin, rmax, nCirclesToExtract, nMinHits, resultCircles_, resultHits, pVisualizationImage))
5235 const int nResultCircles = resultCircles_.
GetSize();
5237 for (
int i = 0; i < nResultCircles; i++)
5239 const Circle2d &circle = resultCircles_[i];
5249 bool ImageProcessor::HoughTransformCircles(
const CVec2dArray &edgePoints,
const CVec2dArray &edgeDirections,
int width,
int height,
int rmin,
int rmax,
int nCirclesToExtract,
int nMinHits,
CCircle2dArray &resultCircles,
CIntArray &resultHits,
CByteImage *pVisualizationImage)
5252 resultCircles.
Clear();
5256 printf(
"error: rmin (%i) may not be greater than rmax (%i) for ImageProcessor::HoughTransformCircles\n", rmin, rmax);
5260 const int n = width + 2 * rmax;
5261 const int m = height + 2 * rmax;
5262 const int nHoughPixels = n * m * (rmax - rmin + 1);
5264 short *houghspace =
new short[nHoughPixels];
5267 memset(houghspace, 0, nHoughPixels *
sizeof(
short));
5273 const int mn = m *
n;
5274 short *helper = houghspace - rmin * mn + rmax * m + rmax;
5277 const int nEdgePoints = edgePoints.
GetSize();
5279 for (
int i = 0; i < nEdgePoints; i++)
5281 const Vec2d &point = edgePoints[i];
5282 const Vec2d &direction = edgeDirections[i];
5284 const float u = point.
x + 0.5f;
5285 const float v = point.
y + 0.5f;
5287 const float angle = atan2f(direction.
y, direction.
x) +
FLOAT_PI;
5290 const int t1 = t0 - 3;
5291 const int t2 = t0 + 3;
5293 for (
int t = t1;
t <= t2;
t++)
5295 for (
int r = rmin;
r <= rmax;
r++)
5301 helper[
r * mn + um * m + vm]++;
5305 helper[
r * mn + um * m + vm]++;
5312 resultCircles.
Clear();
5315 for (
int nn = 0; nn < nCirclesToExtract; nn++)
5317 int max = nMinHits - 1, best_i = -1;
5319 for (
int i = 0; i < nHoughPixels; i++)
5321 if (houghspace[i] > max)
5323 max = houghspace[i];
5330 int um = (best_i % mn) / m;
5331 int vm = (best_i % mn) % m;
5332 int r = best_i / mn;
5336 for (
int j = -w; j <=
w; j++)
5338 for (
int k = -w; k <=
w; k++)
5340 for (
int l = -w; l <=
w; l++)
5346 if (um_ >= 0 && um_ < n && vm >= 0 && vm < m && r_ >= 0 && r_ <= rmax - rmin)
5347 houghspace[r_ * mn + um_ * m + vm_] = 0;
5360 circle.
radius = float(r);
5365 if (pVisualizationImage)
5372 delete [] houghspace;
5380 float &a1,
float &a2,
float &a3,
float &a4,
float &a5,
float &a6,
float &a7,
float &a8)
5400 float &a1,
float &a2,
float &a3,
float &a4,
float &a5,
float &a6)
5422 printf(
"error: input image must be of type CByteImage::eRGB24 or CByteImage::eRGB24Split for ImageProcessor::NormalizeColor\n");
5428 printf(
"error: input and output image must be of same size and type for ImageProcessor::NormalizeColor\n");
5432 const int nPixels = pInputImage->
width * pInputImage->
height;
5435 int redHistogram[256], greenHistogram[256], blueHistogram[256];
5436 float fNormalizeConstant = 255.0f / nPixels;
5440 memset(redHistogram, 0,
sizeof(redHistogram));
5441 memset(greenHistogram, 0,
sizeof(greenHistogram));
5442 memset(blueHistogram, 0,
sizeof(blueHistogram));
5446 for (i = 0; i < nPixels; i++)
5448 redHistogram[input[
offset]]++;
5449 greenHistogram[input[offset + 1]]++;
5450 blueHistogram[input[offset + 2]]++;
5455 for (i = 1; i < 256; i++)
5457 redHistogram[i] += redHistogram[i - 1];
5458 greenHistogram[i] += greenHistogram[i - 1];
5459 blueHistogram[i] += blueHistogram[i - 1];
5462 for (i = 0; i < 256; i++)
5464 redHistogram[i] = int(redHistogram[i] * fNormalizeConstant + 0.5f);
5465 greenHistogram[i] = int(greenHistogram[i] * fNormalizeConstant + 0.5f);
5466 blueHistogram[i] = int(blueHistogram[i] * fNormalizeConstant + 0.5f);
5472 const unsigned char *input_r =
input;
5473 const unsigned char *input_g = input_r + nPixels;
5474 const unsigned char *input_b = input_g + nPixels;
5475 unsigned char *output_r = pOutputImage->
pixels;
5476 unsigned char *output_g = output_r + nPixels;
5477 unsigned char *output_b = output_g + nPixels;
5479 for (
int i = 0; i < nPixels; i++)
5481 output_r[i] = redHistogram[input_r[i]];
5482 output_g[i] = greenHistogram[input_g[i]];
5483 output_b[i] = blueHistogram[input_b[i]];
5488 unsigned char *output = pOutputImage->
pixels;
5490 for (
int i = 0, offset = 0; i < nPixels; i++, offset += 3)
5493 output[offset + 1] = greenHistogram[input[offset + 1]];
5494 output[offset + 2] = blueHistogram[input[offset + 2]];
5506 printf(
"error: input and output matrix do not match for ImageProcessor::GaussianSmooth5x5\n");
5510 if (pInputImage->
columns < 5 || pInputImage->
rows < 5)
5512 printf(
"error: matrices must be at least of size 5x5 for ImageProcessor::GaussianSmooth5x5\n");
5516 const int nKernelSize = 5;
5519 float pFilter[nKernelSize];
5524 for (i = 0; i < nKernelSize; i++)
5526 pFilter[i] = expf(-(i - k) * (i - k) / (2.0f * fVariance));
5530 for (i = 0; i < nKernelSize; i++)
5540 float *temp = pTempImage->
data;
5541 float *output = pOutputImage->
data;
5547 for (y = 0, offset = 0; y <
height; y++)
5549 for (x = 0; x < k; x++, offset++)
5553 for (d = -k; d < -
x; d++)
5554 sum += input[y * width] * pFilter[k + d];
5556 for (d = -x; d <= k; d++)
5557 sum += input[offset + d] * pFilter[k + d];
5563 for (x = 2 * k; x <
width; x++, offset++)
5566 input[offset - 2] * pFilter[0] +
5567 input[offset - 1] * pFilter[1] +
5568 input[
offset] * pFilter[2] +
5569 input[offset + 1] * pFilter[3] +
5570 input[offset + 2] * pFilter[4];
5573 for (x = width - k; x <
width; x++, offset++)
5577 for (d = -k; d < width -
x; d++)
5578 sum += input[offset + d] * pFilter[k + d];
5580 for (d = width - x; d <= k; d++)
5581 sum += input[y * width + width - 1] * pFilter[k + d];
5589 for (y = 0; y < k; y++)
5591 for (x = 0; x <
width; x++)
5595 for (d = -k; d < -
y; d++)
5596 sum += temp[x] * pFilter[k + d];
5598 for (d = -y; d <= k; d++)
5599 sum += temp[(y + d) * width +
x] * pFilter[k + d];
5601 output[y * width +
x] = sum;
5606 for (y = 2 * k, offset = k * width; y <
height; y++)
5608 for (x = 0; x <
width; x++, offset++)
5611 temp[offset - (width << 1)] * pFilter[0] +
5612 temp[offset - width] * pFilter[1] +
5613 temp[offset] * pFilter[2] +
5614 temp[offset + width] * pFilter[3] +
5615 temp[offset + (width << 1)] * pFilter[4];
5619 for (y = height - k; y <
height; y++)
5621 for (x = 0; x <
width; x++)
5625 for (d = -k; d < height -
y; d++)
5626 sum += temp[(y + d) * width +
x] * pFilter[k + d];
5628 for (d = height - y; d < k; d++)
5629 sum += temp[(height - 1) * width +
x] * pFilter[k + d];
5631 output[y * width +
x] = sum;
5645 printf(
"error: input and output image do not match for ImageProcessor::GaussianSmooth\n");
5649 if (pInputImage->
width < nKernelSize || pInputImage->
height < nKernelSize)
5651 printf(
"error: image must be at least of size nKernelSize x nKernelSize for ImageProcessor::GaussianSmooth\n");
5655 const int k = (nKernelSize - 1) / 2;
5657 float *pFilter =
new float[nKernelSize];
5662 for (i = 0; i < nKernelSize; i++)
5664 pFilter[i] = expf(-(i - k) * (i - k) / (2.0f * fVariance));
5668 for (i = 0; i < nKernelSize; i++)
5678 unsigned char *temp = pTempImage->
pixels;
5679 unsigned char *output = pOutputImage->
pixels;
5685 for (y = 0, offset = 0; y <
height; y++)
5687 for (x = 0; x < k; x++, offset++)
5691 for (d = -k; d < -
x; d++)
5692 sum += input[y * width] * pFilter[k + d];
5694 for (d = -x; d <= k; d++)
5695 sum += input[offset + d] * pFilter[k + d];
5697 temp[
offset] = (
unsigned char) (sum + 0.5f);
5701 for (x = 2 * k; x <
width; x++, offset++)
5705 for (d = -k; d <= k; d++)
5706 sum += input[offset + d] * pFilter[d + k];
5708 temp[
offset] = (
unsigned char) (sum + 0.5f);
5711 for (x = width - k; x <
width; x++, offset++)
5715 for (d = -k; d < width -
x; d++)
5716 sum += input[offset + d] * pFilter[k + d];
5718 for (d = width - x; d <= k; d++)
5719 sum += input[y * width + width - 1] * pFilter[k + d];
5721 temp[
offset] = (
unsigned char) (sum + 0.5f);
5727 for (y = 0; y < k; y++)
5729 for (x = 0; x <
width; x++)
5733 for (d = -k; d < -
y; d++)
5734 sum += temp[x] * pFilter[k + d];
5736 for (d = -y; d <= k; d++)
5737 sum += temp[(y + d) * width +
x] * pFilter[k + d];
5739 output[y * width +
x] = (
unsigned char) (sum + 0.5f);
5744 for (y = 2 * k, offset = k * width; y <
height; y++)
5746 for (x = 0; x <
width; x++, offset++)
5750 for (d = -k; d <= k; d++)
5751 sum += temp[offset + d * width] * pFilter[d + k];
5753 output[
offset] = (
unsigned char) (sum + 0.5f);
5757 for (y = height - k; y <
height; y++)
5759 for (x = 0; x <
width; x++)
5763 for (d = -k; d < height -
y; d++)
5764 sum += temp[(y + d) * width +
x] * pFilter[k + d];
5766 for (d = height - y; d < k; d++)
5767 sum += temp[(height - 1) * width +
x] * pFilter[k + d];
5769 output[y * width +
x] = (
unsigned char) (sum + 0.5f);
5784 printf(
"error: input image and output matrix do not match for ImageProcessor::GaussianSmooth\n");
5788 if (pInputImage->
width < nKernelSize || pInputImage->
height < nKernelSize)
5790 printf(
"error: image must be at least of size nKernelSize x nKernelSize for ImageProcessor::GaussianSmooth\n");
5794 const int k = (nKernelSize - 1) / 2;
5796 float *pFilter =
new float[nKernelSize];
5801 for (i = 0; i < nKernelSize; i++)
5803 pFilter[i] = expf(-(i - k) * (i - k) / (2.0f * fVariance));
5807 for (i = 0; i < nKernelSize; i++)
5817 float *temp = pTempImage->
data;
5818 float *output = pOutputImage->
data;
5824 for (y = 0, offset = 0; y <
height; y++)
5826 for (x = 0; x < k; x++, offset++)
5830 for (d = -k; d < -
x; d++)
5831 sum += input[y * width] * pFilter[k + d];
5833 for (d = -x; d <= k; d++)
5834 sum += input[offset + d] * pFilter[k + d];
5840 for (x = 2 * k; x <
width; x++, offset++)
5844 for (d = -k; d <= k; d++)
5845 sum += input[offset + d] * pFilter[d + k];
5850 for (x = width - k; x <
width; x++, offset++)
5854 for (d = -k; d < width -
x; d++)
5855 sum += input[offset + d] * pFilter[k + d];
5857 for (d = width - x; d <= k; d++)
5858 sum += input[y * width + width - 1] * pFilter[k + d];
5866 for (y = 0; y < k; y++)
5868 for (x = 0; x <
width; x++)
5872 for (d = -k; d < -
y; d++)
5873 sum += temp[x] * pFilter[k + d];
5875 for (d = -y; d <= k; d++)
5876 sum += temp[(y + d) * width +
x] * pFilter[k + d];
5878 output[y * width +
x] = sum;
5883 for (y = 2 * k, offset = k * width; y <
height; y++)
5885 for (x = 0; x <
width; x++, offset++)
5889 for (d = -k; d <= k; d++)
5890 sum += temp[offset + d * width] * pFilter[d + k];
5896 for (y = height - k; y <
height; y++)
5898 for (x = 0; x <
width; x++)
5902 for (d = -k; d < height -
y; d++)
5903 sum += temp[(y + d) * width +
x] * pFilter[k + d];
5905 for (d = height - y; d < k; d++)
5906 sum += temp[(height - 1) * width +
x] * pFilter[k + d];
5908 output[y * width +
x] = sum;
5923 printf(
"error: input and output matrix do not match for ImageProcessor::GaussianSmooth\n");
5927 if (pInputImage->
columns < nKernelSize || pInputImage->
rows < nKernelSize)
5929 printf(
"error: matrix must be at least of size nKernelSize x nKernelSize for ImageProcessor::GaussianSmooth\n");
5933 const int k = (nKernelSize - 1) / 2;
5935 float *pFilter =
new float[nKernelSize];
5940 for (i = 0; i < nKernelSize; i++)
5942 pFilter[i] = expf(-(i - k) * (i - k) / (2.0f * fVariance));
5946 for (i = 0; i < nKernelSize; i++)
5956 float *temp = pTempImage->
data;
5957 float *output = pOutputImage->
data;
5963 for (y = 0, offset = 0; y <
height; y++)
5965 for (x = 0; x < k; x++, offset++)
5969 for (d = -k; d < -
x; d++)
5970 sum += input[y * width] * pFilter[k + d];
5972 for (d = -x; d <= k; d++)
5973 sum += input[offset + d] * pFilter[k + d];
5979 for (x = 2 * k; x <
width; x++, offset++)
5983 for (d = -k; d <= k; d++)
5984 sum += input[offset + d] * pFilter[d + k];
5989 for (x = width - k; x <
width; x++, offset++)
5993 for (d = -k; d < width -
x; d++)
5994 sum += input[offset + d] * pFilter[k + d];
5996 for (d = width - x; d <= k; d++)
5997 sum += input[y * width + width - 1] * pFilter[k + d];
6005 for (y = 0; y < k; y++)
6007 for (x = 0; x <
width; x++)
6011 for (d = -k; d < -
y; d++)
6012 sum += temp[x] * pFilter[k + d];
6014 for (d = -y; d <= k; d++)
6015 sum += temp[(y + d) * width +
x] * pFilter[k + d];
6017 output[y * width +
x] = sum;
6022 for (y = 2 * k, offset = k * width; y <
height; y++)
6024 for (x = 0; x <
width; x++, offset++)
6028 for (d = -k; d <= k; d++)
6029 sum += temp[offset + d * width] * pFilter[d + k];
6035 for (y = height - k; y <
height; y++)
6037 for (x = 0; x <
width; x++)
6041 for (d = -k; d < height -
y; d++)
6042 sum += temp[(y + d) * width +
x] * pFilter[k + d];
6044 for (d = height - y; d < k; d++)
6045 sum += temp[(height - 1) * width +
x] * pFilter[k + d];
6047 output[y * width +
x] = sum;
6062 printf(
"error: input and output image do not match for ImageProcessor::HighPassX3\n");
6067 if (pInputImage->
data == pOutputImage->
data)
6069 pSaveOutputImage = pOutputImage;
6074 float *output = pOutputImage->
data;
6083 const int max = offset + width - 1;
6086 for (
int x = offset + 1;
x < max;
x++)
6087 output[
x] = (input[
x + 1] - input[
x - 1]) * 0.5f;
6089 output[offset + width - 1] = input[offset + width - 1] - input[offset + width - 2];
6092 if (pSaveOutputImage)
6095 delete pOutputImage;
6105 printf(
"error: input and output image do not match for ImageProcessor::HighPassY3\n");
6110 if (pInputImage->
data == pOutputImage->
data)
6112 pSaveOutputImage = pOutputImage;
6117 float *output = pOutputImage->
data;
6124 for (x = 0; x <
width; x++)
6125 output[x] = input[x + width] - input[x];
6131 for (x = (height - 1) * width; x <
width; x++)
6132 output[x] = input[x] - input[x - width];
6134 if (pSaveOutputImage)
6137 delete pOutputImage;
6146 pInputImage->
type != pOutputImage->
type)
6148 printf(
"error: input and output image do not match for ImageProcessor::FlipY\n");
6154 const int nPixels = width *
height;
6160 const int h = height / 2;
6164 unsigned char *temp =
new unsigned char[
width];
6165 unsigned char *output = pOutputImage->
pixels + nPixels -
width;
6167 for (
int y = 0;
y < h;
y++)
6169 memcpy(temp, output, width);
6170 memcpy(output, input, width);
6171 memcpy(input, temp, width);
6181 const int nWidthBytes = 3 *
width;
6183 unsigned char *temp =
new unsigned char[nWidthBytes];
6184 unsigned char *output = pOutputImage->
pixels + 3 * nPixels - nWidthBytes;
6186 for (
int y = 0;
y < h;
y++)
6188 memcpy(temp, output, nWidthBytes);
6189 memcpy(output, input, nWidthBytes);
6190 memcpy(input, temp, nWidthBytes);
6192 input += nWidthBytes;
6193 output -= nWidthBytes;
6203 unsigned char *output = pOutputImage->
pixels + nPixels -
width;
6207 memcpy(output, input, width);
6215 const int nWidthBytes = 3 *
width;
6216 unsigned char *output = pOutputImage->
pixels + 3 * nPixels - nWidthBytes;
6220 memcpy(output, input, nWidthBytes);
6222 input += nWidthBytes;
6223 output -= nWidthBytes;
6235 printf(
"error: input and output image do not match for ImageProcessor::CalculateIntegralImage\n");
6243 int *output = pIntegralImage->
pixels;
6252 *output = *input++ + *(output - 1);
6260 *output = *input++ + *(output -
width);
6266 *output = *input++ + *(output - 1) + *(output - width) - *(output - width - 1);
6278 printf(
"error: input and output image do not match for ImageProcessor::CalculateSummedAreaTable\n");
6290 printf(
"error: input and output image do not match for ImageProcessor::CalculateBinarizedSummedAreaTable\n");
6298 int *output = pSummedAreaTable->
pixels;
6302 c = (c != 0 ? 1 : 0);
6310 c = (c != 0 ? 1 : 0);
6312 *output = c + *(output-1);
6321 c = (c != 0 ? 1 : 0);
6323 *output = c + *(output -
width);
6330 c = (c != 0 ? 1 : 0);
6332 *output = c + *(output-1) + *(output - width) - *(output - width - 1);
6344 printf(
"error: input and output image do not match for ImageProcessor::CalculateReverseSummedAreaTable\n");
6352 unsigned char *output = pOutputImage->
pixels;
6362 *output++ = c - *(input - 2);
6370 *output++ = c - *(input - width - 1);
6376 *output++ = c - *(input - 2) - *(input - width - 1) + *(input - width - 2);
6392 if (min_x >= width) min_x = width - 1;
6393 if (max_x < 0) max_x = 0;
6394 if (max_x >= width) max_x = width - 1;
6395 if (min_y >= height) min_y = height - 1;
6396 if (max_y < 0) max_y = 0;
6397 if (max_y >= height) max_y = height - 1;
6400 const int c1 = min_x < 0 || min_y < 0 ? 0 : pixels[min_y * width + min_x];
6401 const int c2 = min_y < 0 ? 0 : pixels[min_y * width + max_x];
6402 const int c3 = min_x < 0 ? 0 : pixels[max_y * width + min_x];
6403 const int c4 = pixels[max_y * width + max_x];
6405 return c4 - c3 - c2 + c1;
6417 return pixels[max_y * width + max_x] - pixels[max_y * width + min_x] - pixels[min_y * width + max_x] + pixels[min_y * width + min_x];
6434 const int offset = stack[sp];
6436 if (magnitudes[offset - width - 1] == 1)
6438 stack[sp++] = offset - width - 1;
6439 magnitudes[offset - width - 1] = 255;
6442 if (magnitudes[offset + width + 1] == 1)
6444 stack[sp++] = offset + width + 1;
6445 magnitudes[offset + width + 1] = 255;
6448 if (magnitudes[offset - width + 1] == 1)
6450 stack[sp++] = offset - width + 1;
6451 magnitudes[offset - width + 1] = 255;
6454 if (magnitudes[offset + width - 1] == 1)
6456 stack[sp++] = offset + width - 1;
6457 magnitudes[offset + width - 1] = 255;
6460 if (magnitudes[offset - width] == 1)
6462 stack[sp++] = offset -
width;
6463 magnitudes[offset -
width] = 255;
6466 if (magnitudes[offset + width] == 1)
6468 stack[sp++] = offset +
width;
6469 magnitudes[offset +
width] = 255;
6472 if (magnitudes[offset - 1] == 1)
6474 stack[sp++] = offset - 1;
6475 magnitudes[offset - 1] = 255;
6478 if (magnitudes[offset + 1] == 1)
6480 stack[sp++] = offset + 1;
6481 magnitudes[offset + 1] = 255;
6493 printf(
"error: input and output image do not match for ImageProcessor::Canny\n");
6497 if (nLowThreshold == 0) nLowThreshold = 1;
6498 if (nHighThreshold == 0) nHighThreshold = 1;
6502 const int nPixels = width *
height;
6504 CShortImage gradientsX(width, height), gradientsY(width, height);
6505 SobelX(pInputImage, &gradientsX,
false);
6506 SobelY(pInputImage, &gradientsY,
false);
6510 unsigned char *output = pOutputImage->
pixels;
6511 short *magnitudes = gradientsX.pixels;
6516 for (i = 0; i < nPixels; i++)
6518 const int gx = gradientsX.pixels[i];
6519 const int gy = gradientsY.
pixels[i];
6520 const int agx = abs(gx);
6521 const int agy = abs(gy);
6522 const int g = agx + agy;
6527 if (g >= nLowThreshold)
6529 if (agx > (agy << 1))
6533 else if ((agx << 1) > agy)
6535 output[i] = gx * gy >= 0 ? 12 : 13;
6545 for (i = 0; i < nPixels; i++)
6547 const int g = (int) magnitudes[i];
6549 if (g >= nLowThreshold)
6554 if (magnitudes[i + 1] <= g && magnitudes[i - 1] < g)
6555 output[i] = g >= nHighThreshold ? 254 : 1;
6559 if (magnitudes[i + width] <= g && magnitudes[i - width] < g)
6560 output[i] = g >= nHighThreshold ? 254 : 1;
6564 if (magnitudes[i + width + 1] <= g && magnitudes[i - width - 1] < g)
6565 output[i] = g >= nHighThreshold ? 254 : 1;
6569 if (magnitudes[i + width - 1] <= g && magnitudes[i - width + 1] < g)
6570 output[i] = g >= nHighThreshold ? 254 : 1;
6577 int *stack =
new int[nPixels];
6579 for (i = 0; i < nPixels; i++)
6580 if (output[i] == 254)
6582 track(output, stack, i, width);
6586 for (i = 0; i < nPixels; i++)
6588 if (output[i] != 255)
6606 a = *input - *(input - 2);
6607 b = *(input + 1) - *(input - 1);
6608 c = *(input + 2) - *input;
6613 const float x = 0.5f * (a -
c) / n;
6615 if (fabsf(x) < 1.0f)
6619 else if (sector == 1)
6621 a = *input - *(input - (width << 1));
6622 b = *(input +
width) - *(input - width);
6623 c = *(input + (width << 1)) - *
input;
6628 const float y = 0.5f * (a -
c) / n;
6630 if (fabsf(y) < 1.0f)
6634 else if (sector == 2)
6636 a = *input - *(input - (width << 1) - 2);
6637 b = *(input + width + 1) - *(input - width - 1);
6638 c = *(input + (width << 1) + 2) - *
input;
6643 const float xy = 0.35355339059327378637f * (a -
c) / n;
6645 if (fabsf(xy) < 1.0f)
6652 else if (sector == 3)
6654 a = *input - *(input - (width << 1) + 2);
6655 b = *(input + width - 1) - *(input - width + 1);
6656 c = *(input + (width << 1) - 2) - *
input;
6661 const float xy = 0.35355339059327378637f * (a -
c) / n;
6663 if (fabsf(xy) < 1.0f)
6672 (
float) ((input[1] << 1) + input[1 - width] + input[1 + width] - (input[-1] << 1) - input[-1 - width] - input[-1 + width]),
6673 (
float) ((input[width] << 1) + input[width - 1] + input[width + 1] - (input[-width] << 1) - input[-width - 1] - input[-width + 1]));
6683 printf(
"error: input image must be of type eGrayScale for ImageProcessor::Canny (list)\n");
6687 if (nLowThreshold == 0) nLowThreshold = 1;
6688 if (nHighThreshold == 0) nHighThreshold = 1;
6692 const int nPixels = width *
height;
6694 CShortImage gradientsX(width, height), gradientsY(width, height);
6695 SobelX(pInputImage, &gradientsX,
false);
6696 SobelY(pInputImage, &gradientsY,
false);
6703 unsigned char *temp = tempImage.
pixels;
6704 unsigned char *sectors = sectorImage.
pixels;
6705 short *magnitudes = gradientsX.pixels;
6710 for (i = 0; i < nPixels; i++)
6712 const int gx = gradientsX.pixels[i];
6713 const int gy = gradientsY.
pixels[i];
6714 const int agx = abs(gx);
6715 const int agy = abs(gy);
6716 const int g = agx + agy;
6721 if (g >= nLowThreshold)
6723 if (agx > (agy << 1))
6727 else if ((agx << 1) > agy)
6729 sectors[i] = gx * gy >= 0 ? 2 : 3;
6739 for (i = 0; i < nPixels; i++)
6741 const int g = (int) magnitudes[i];
6743 if (g >= nLowThreshold)
6748 if (magnitudes[i + 1] <= g && magnitudes[i - 1] < g)
6749 temp[i] = g >= nHighThreshold ? 254 : 1;
6753 if (magnitudes[i + width] <= g && magnitudes[i - width] < g)
6754 temp[i] = g >= nHighThreshold ? 254 : 1;
6758 if (magnitudes[i + width + 1] <= g && magnitudes[i - width - 1] < g)
6759 temp[i] = g >= nHighThreshold ? 254 : 1;
6763 if (magnitudes[i + width - 1] <= g && magnitudes[i - width + 1] < g)
6764 temp[i] = g >= nHighThreshold ? 254 : 1;
6771 int *stack =
new int[nPixels];
6773 for (i = 0; i < nPixels; i++)
6776 track(temp, stack, i, width);
6780 resultPoints.
Clear();
6781 resultDirections.
Clear();
6784 for (i = height - 4, offset = 2 * width + 2; i; i--, offset += 4)
6785 for (
int j = width - 4; j; j--, offset++)
6786 if (temp[offset] == 255)
6789 Math2d::SetVec(point, (
float) (offset % width), (
float) (offset / width));
6807 #define HARRIS_WINDOW_SIZE 3 // don't change this define 6813 printf(
"error: input image and output matrix do not match for ImageProcessor::CalculateHarrisMap\n");
6819 const int nPixels = width *
height;
6825 int *cov =
new int[3 * nPixels];
6828 const int stop = nPixels - width - 1;
6829 for (offset = width + 1; offset < stop; offset++)
6831 const int p = int(input[offset + 1]) - int(input[offset - 1]);
6832 const int q = int(input[offset + width]) - int(input[offset - width]);
6833 const int offset_ = 3 *
offset;
6835 cov[offset_ ] = p *
p;
6836 cov[offset_ + 1] = q *
q;
6837 cov[offset_ + 2] = p *
q;
6845 const int width3 = 3 *
width;
6849 for (i = diff, offset = width + 1; i <
height; i++, offset += diff)
6851 for (j = diff; j <
width; j++, offset++)
6857 for (
int k = 0, offset2 = 3 * offset; k <
HARRIS_WINDOW_SIZE; k++, offset2 += width3)
6859 ppsum += cov[offset2];
6860 qqsum += cov[offset2 + 1];
6861 pqsum += cov[offset2 + 2];
6862 ppsum += cov[offset2 + 3];
6863 qqsum += cov[offset2 + 4];
6864 pqsum += cov[offset2 + 5];
6865 ppsum += cov[offset2 + 6];
6866 qqsum += cov[offset2 + 7];
6867 pqsum += cov[offset2 + 8];
6881 R[
offset] = (ppsum * qqsum - pqsum * pqsum) - (((ppsum + qqsum) >> 2) * ((ppsum + qqsum) >> 2));
6896 const int x = pValues[pOffsets[(nLow + nHigh) >> 1]];
6900 while (pValues[pOffsets[i]] > x) i++;
6901 while (pValues[pOffsets[j]] < x) j--;
6905 const int temp = pOffsets[i];
6906 pOffsets[i] = pOffsets[j];
6924 printf(
"error: input image should be grayscale ImageProcessor::CalculateHarrisInterestPoints\n");
6930 const int nPixels = width *
height;
6941 for (i = 0; i < nPixels; ++i)
6947 int *pCandidateOffsets =
new int[nPixels];
6948 int nCandidates = 0;
6951 max = int(max * fQualityLevel + 0.5f);
6952 for (i = 0; i < nPixels; i++)
6955 pCandidateOffsets[nCandidates++] = i;
6962 const int nMinDistance = int(fMinDistance + 0.5f);
6965 int nInterestPoints = 0;
6966 for (i = 0; i < nCandidates && nInterestPoints < nMaxPoints; i++)
6968 const int offset = pCandidateOffsets[i];
6970 const int x = offset %
width;
6971 const int y = offset /
width;
6975 const int minx = x - nMinDistance < 0 ? 0 : x - nMinDistance;
6976 const int miny = y - nMinDistance < 0 ? 0 : y - nMinDistance;
6977 const int maxx = x + nMinDistance >= width ? width - 1 : x + nMinDistance;
6978 const int maxy = y + nMinDistance >= height ? height - 1 : y + nMinDistance;
6979 const int diff = width - (maxx - minx + 1);
6981 for (
int l = miny, offset2 = miny * width + minx; l <= maxy; l++, offset2 += diff)
6982 for (
int k = minx; k <= maxx; k++, offset2++)
6983 if (image.
pixels[l * width + k])
6992 pInterestPoints[nInterestPoints].
x = float(x);
6993 pInterestPoints[nInterestPoints].
y = float(y);
7001 delete [] pCandidateOffsets;
7003 return nInterestPoints;
7013 printf(
"error: input images and output image do not match for ImageProcessor::And\n");
7019 const unsigned char *input1 = pInputImage1->
pixels;
7020 const unsigned char *input2 = pInputImage2->
pixels;
7021 unsigned char *output = pOutputImage->
pixels;
7022 for (
int i = 0; i < nBytes; i++)
7023 output[i] = input1[i] & input2[i];
7036 printf(
"error: input images and output image do not match for ImageProcessor::Xor\n");
7042 const unsigned char *input1 = pInputImage1->
pixels;
7043 const unsigned char *input2 = pInputImage2->
pixels;
7044 unsigned char *output = pOutputImage->
pixels;
7045 for (
int i = 0; i < nBytes; i++)
7046 output[i] = input1[i] ^ input2[i];
7059 printf(
"error: input images and output image do not match for ImageProcessor::Or\n");
7065 const unsigned char *input1 = pInputImage1->
pixels;
7066 const unsigned char *input2 = pInputImage2->
pixels;
7067 unsigned char *output = pOutputImage->
pixels;
7068 for (
int i = 0; i < nBytes; i++)
7069 output[i] = input1[i] | input2[i];
7083 printf(
"error: input images and output image do not match for ImageProcessor::Add\n");
7089 const unsigned char *input1 = pInputImage1->
pixels;
7090 const unsigned char *input2 = pInputImage2->
pixels;
7091 unsigned char *output = pOutputImage->
pixels;
7093 for (
int i = 0; i < nBytes; i++)
7094 output[i] = input1[i] + input2[i];
7107 printf(
"error: input images and output image do not match for ImageProcessor::AddAndSaturate\n");
7113 const unsigned char *input1 = pInputImage1->
pixels;
7114 const unsigned char *input2 = pInputImage2->
pixels;
7115 unsigned char *output = pOutputImage->
pixels;
7117 for (
int i = 0; i < nBytes; i++)
7118 output[i] =
MY_MIN((
unsigned int) input1[i] + (
unsigned int) input2[i], 255);
7131 printf(
"error: input images and output image do not match for ImageProcessor::Subtract\n");
7137 const unsigned char *input1 = pInputImage1->
pixels;
7138 const unsigned char *input2 = pInputImage2->
pixels;
7139 unsigned char *output = pOutputImage->
pixels;
7141 for (
int i = 0; i < nBytes; i++)
7142 output[i] = input1[i] - input2[i];
7155 printf(
"error: input images and output image do not match for ImageProcessor::SubtractAndSaturate\n");
7161 const unsigned char *input1 = pInputImage1->
pixels;
7162 const unsigned char *input2 = pInputImage2->
pixels;
7163 unsigned char *output = pOutputImage->
pixels;
7165 for (
int i = 0; i < nBytes; i++)
7166 output[i] =
MY_MAX((
int) input1[i] - (
int) input2[i], 0);
7179 printf(
"error: input images and output image do not match for ImageProcessor::AbsoluteDifference\n");
7185 const unsigned char *input1 = pInputImage1->
pixels;
7186 const unsigned char *input2 = pInputImage2->
pixels;
7187 unsigned char *output = pOutputImage->
pixels;
7189 for (
int i = 0; i < nBytes; i++)
7190 output[i] = abs((
int) input1[i] - (
int) input2[i]);
7203 printf(
"error: input images and output image do not match for ImageProcessor::Average\n");
7209 const unsigned char *input1 = pInputImage1->
pixels;
7210 const unsigned char *input2 = pInputImage2->
pixels;
7211 unsigned char *output = pOutputImage->
pixels;
7213 for (
int i = 0; i < nBytes; i++)
7214 output[i] = ((
unsigned int) input1[i] + (
unsigned int) input2[i] + 1) >> 1;
7227 printf(
"error: input images and output image do not match for ImageProcessor::Min\n");
7233 const unsigned char *input1 = pInputImage1->
pixels;
7234 const unsigned char *input2 = pInputImage2->
pixels;
7235 unsigned char *output = pOutputImage->
pixels;
7237 for (
int i = 0; i < nBytes; i++)
7238 output[i] =
MY_MIN(input1[i], input2[i]);
7251 printf(
"error: input images and output image do not match for ImageProcessor::Max\n");
7257 const unsigned char *input1 = pInputImage1->
pixels;
7258 const unsigned char *input2 = pInputImage2->
pixels;
7259 unsigned char *output = pOutputImage->
pixels;
7261 for (
int i = 0; i < nBytes; i++)
7262 output[i] =
MY_MAX(input1[i], input2[i]);
7278 printf(
"error: input image must be of type eGrayScale for ImageProcessor::MaxValue\n");
7282 const int nPixels = pInputImage->
width * pInputImage->
height;
7286 for (
int i = 0; i < nPixels; i++)
7303 const int nPixels = pInputImage->
width * pInputImage->
height;
7307 for (
int i = 0; i < nPixels; i++)
7324 const int nPixels = pInputImage->
width * pInputImage->
height;
7328 for (
int i = 0; i < nPixels; i++)
7347 printf(
"error: input image must be of type eGrayScale for ImageProcessor::MinValue\n");
7351 const int nPixels = pInputImage->
width * pInputImage->
height;
7355 for (
int i = 0; i < nPixels; i++)
7372 const int nPixels = pInputImage->
width * pInputImage->
height;
7376 for (
int i = 0; i < nPixels; i++)
7393 const int nPixels = pInputImage->
width * pInputImage->
height;
7397 for (
int i = 0; i < nPixels; i++)
7414 printf(
"error: input image must be of type eGrayScale for ImageProcessor::MinMaxValue\n");
7418 const int nPixels = pInputImage->
width * pInputImage->
height;
7423 for (
int i = 0; i < nPixels; i++)
7441 const int nPixels = pInputImage->
width * pInputImage->
height;
7446 for (
int i = 0; i < nPixels; i++)
7462 const int nPixels = pInputImage->
width * pInputImage->
height;
7467 for (
int i = 0; i < nPixels; i++)
7482 unsigned int sum = 0;
7488 printf(
"error: input image must be of type eGrayScale for ImageProcessor::PixelSum\n");
7492 const int nPixels = pImage->
width * pImage->
height;
7495 for (
int i = 0; i < nPixels; i++)
7552 printf(
"error: input image must be of type eGrayScale and output image of type eRGB24 for ImageProcessor::ConvertBayerPattern\n");
7557 unsigned char *output = pOutputImage->
pixels;
7561 const int width3 = 3 *
width;
7566 memset(output, 0, width);
7567 memset(output + (height - 1) * width, 0, width);
7569 for (
int i = 2, input_offset = 0, output_offset = width3 + 4; i <
height; i++, input_offset +=
width, output_offset += width3)
7571 const unsigned char *bayer = input + input_offset;
7572 const unsigned char *bayer_end = bayer + width - 4;
7573 unsigned char *
dst = output + output_offset;
7575 dst[-4] = dst[-3] = dst[-2] = 0;
7579 dst[
blue] = (
unsigned char) ((bayer[1] + bayer[2 * width + 1] + 1) >> 1);
7580 dst[0] = bayer[width + 1];
7581 dst[-
blue] = (
unsigned char) ((bayer[width] + bayer[width + 2] + 1) >> 1);
7589 for (; bayer <= bayer_end; bayer += 2, dst += 6)
7591 register int v = bayer[2] + bayer[2 * width + 2] + 1;
7593 dst[4] = (
unsigned char) (v >> 1);
7594 dst[3] = bayer[width + 2];
7595 dst[2] = (
unsigned char) ((bayer[width + 1] + bayer[width + 3] + 1) >> 1);
7597 dst[1] = (
unsigned char) ((bayer[0] + bayer[2 * width] + v + 1) >> 2);
7598 dst[0] = (
unsigned char) ((bayer[1] + bayer[width] + bayer[width + 2] + bayer[2 * width + 1] + 2) >> 2);
7599 dst[-1] = bayer[width + 1];
7604 for (; bayer <= bayer_end; bayer += 2, dst += 6)
7606 register int v = bayer[2] + bayer[2 * width + 2] + 1;
7608 dst[2] = (
unsigned char) (v >> 1);
7609 dst[3] = bayer[width + 2];
7610 dst[4] = (
unsigned char) ((bayer[width + 1] + bayer[width + 3] + 1) >> 1);
7612 dst[-1] = (
unsigned char) ((bayer[0] + bayer[2 * width] + v + 1) >> 2);
7613 dst[0] = (
unsigned char) ((bayer[1] + bayer[width] + bayer[width + 2] + bayer[2 * width + 1] + 2) >> 2);
7614 dst[1] = bayer[width + 1];
7618 if (bayer < bayer_end + 2)
7620 dst[
blue] = (
unsigned char) ((bayer[0] + bayer[2] + bayer[2 * width] + bayer[2 * width + 2] + 2) >> 2);
7621 dst[0] = (
unsigned char) ((bayer[1] + bayer[width] + bayer[width + 2] + bayer[2 * width + 1] + 2) >> 2);
7622 dst[-
blue] = bayer[width + 1];
7628 dst[-1] = dst[0] = dst[1] = 0;
7631 bGreenFirst = !bGreenFirst;
bool HighPassX3(const CFloatMatrix *pInputImage, CFloatMatrix *pOutputImage)
Applies a 1x3 highpass filter to a CFloatMatrix and write the result to a CFloatMatrix.
unsigned int PixelSum(const CByteImage *pImage)
Returns the sum of all pixel values of a grayscale CByteImage.
unsigned char MaxValue(const CByteImage *pImage)
Returns the maximum value within a grayscale CByteImage.
bool AddWithSaturation(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Sets each pixel in a CByteImage to the sum of the corresponding pixels in two instances of CByteImage...
const int * GetColorParameters(ObjectColor color) const
bool DetermineAffineTransformation(const Vec2d *pSourcePoints, const Vec2d *pTargetPoints, int nPoints, float &a1, float &a2, float &a3, float &a4, float &a5, float &a6)
Deprecated.
BayerPatternType
The four possible variants for Bayer pattern conversion.
GLfloat GLfloat GLfloat v2
bool MinMaxValue(const CByteImage *pImage, unsigned char &min, unsigned char &max)
Computes the minimum and maximum value within a grayscale CByteImage.
bool IsCompatible(const CByteImage *pImage) const
Checks whether two images are compatible or not.
#define OPTIMIZED_FUNCTION_HEADER_3(name, p1, p2, p3)
float * pixels
The pointer to the the pixels.
#define OPTIMIZED_FUNCTION_HEADER_4(name, p1, p2, p3, p4)
bool ApplyAffinePointOperation(const CByteImage *pInputImage, CByteImage *pOutputImage, float a, float b)
Applies an affine point operation to a CByteImage and writes the result to a CByteImage.
bool ApplyHomography(const CByteImage *pInputImage, CByteImage *pOutputImage, const Mat3d &A, bool bInterpolation=true)
Applies a homography to a CByteImage and writes the result to a CByteImage.
#define HARRIS_WINDOW_SIZE
bool CopyFrame(const CByteImage *pInputImage, CByteImage *pOutputImage)
Copies all pixels on a one pixel wide frame from one CByteImage to CByteImage.
bool DetermineHomography(const Vec2d *pSourcePoints, const Vec2d *pTargetPoints, int nPoints, Mat3d &A, bool bUseSVD=false)
Determines a homography based on a set of 2d-2d point correspondences.
static void CalculateSubpixel(const unsigned char *input, int width, int sector, Vec2d &point, Vec2d &direction)
bool HoughTransformLines(const CByteImage *pImage, CByteImage *pVisualizationImage, Vec2dList &resultLines, int nLinesToExtract, int nMinHits=1)
Performs the Hough transform for straight lines on a CByteImage.
bool CalculateGradientImageSobel(const CByteImage *pInputImage, CByteImage *pOutputImage)
Applies a combined Sobel filter for both x- and y-direction to a CByteImage and stores the result in ...
Data structure for the representation of a 2D circle.
bool Laplace2(const CByteImage *pInputImage, CShortImage *pOutputImage, bool bAbsoluteValue=true)
Filters a CByteImage with the Laplace2 operator and writes the result to a CShortImage.
bool FilterColor(const CByteImage *pInputImage, CByteImage *pOutputImage, ObjectColor cColor, CColorParameterSet *pColorParameterSet, bool bImageIsHSV=true)
Performs color filtering with binarization for a CByteImage and writes the result to a grayscale CByt...
bool FindRegions(const CByteImage *pImage, RegionList ®ionList, int nMinimumPointsPerRegion=0, int nMaximumPointsPerRegion=0, bool bCalculateBoundingBox=true, bool bStorePixels=false)
Performs region growing on a binary CByteImage, segmenting all regions in the image.
bool Max(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Sets each pixel in a CByteImage to the maximum of the corresponding pixels in two instances of CByteI...
bool CalculateSaturationImage(const CByteImage *pInputImage, CByteImage *pOutputImage)
Calculates the saturation image for an RGB CByteImage and writes the result to a CByteImage.
bool NormalizeColor(const CByteImage *pInputImage, CByteImage *pOutputImage)
Applies histogram equalization to all channels of a color CByteImage.
bool ThresholdFilterInverse(const CByteImage *pInputImage, CByteImage *pOutputImage, unsigned char nThreshold)
Performs inverse threhold filtering to a CByteImage and writes the result to a CByteImage.
bool Dilate(const CByteImage *pInputImage, CByteImage *pOutputImage, int nMaskSize=3, const MyRegion *pROI=0)
Applies a morphological dilate operation to a binary CByteImage and writes the result to a binary CBy...
GLdouble GLdouble GLdouble GLdouble q
bool ThresholdFilter(const CByteImage *pInputImage, CByteImage *pOutputImage, unsigned char nThreshold)
Performs threhold filtering to a CByteImage and writes the result to a CByteImage.
std::vector< Vec2d > Vec2dList
int width
The width of the image in pixels.
bool DetermineHomography(const Vec2d *pSourcePoints, const Vec2d *pTargetPoints, int nPoints, float &a1, float &a2, float &a3, float &a4, float &a5, float &a6, float &a7, float &a8)
Deprecated.
static void QuicksortInverse(int *pOffsets, const int *pValues, int nLow, int nHigh)
bool SobelX(const CByteImage *pInputImage, CShortImage *pOutputImage, bool bAbsoluteValue=true)
Filters a CByteImage with the SobelX operator and writes the result to a CShortImage.
bool FilterRGB(const CByteImage *pInputImage, CByteImage *pOutputImage, CRGBColorModel *pColorModel, float fThreshold)
Performs color filtering with binarization for an RGB CByteImage, given a CRGBColorModel, and writes the result to a grayscale CByteImage.
bool PrewittX(const CByteImage *pInputImage, CShortImage *pOutputImage, bool bAbsoluteValue=true)
Filters a CByteImage with the PrewittX operator and writes the result to a CShortImage.
unsigned char MinValue(const CByteImage *pImage)
Returns the minimum value within a grayscale CByteImage.
bool CalculateBinarizedSummedAreaTable(const CByteImage *pInputImage, CIntImage *pSummedAreaTable)
Calculates the binarized summed area table of a grayscale CByteImage and writes the result to a CIntI...
bool Invert(const CByteImage *pInputImage, CByteImage *pOutputImage)
Calculates the inverted image of a CByteImage and writes the result to a CByteImage.
GLenum GLsizei GLenum GLenum const GLvoid * image
bool ConvertBayerPattern(const CByteImage *pInputImage, CByteImage *pOutputImage, BayerPatternType type)
Converts an 8 bit Bayer pattern CByteImage to an RGB24 color CByteImage.
bool SobelY(const CByteImage *pInputImage, CShortImage *pOutputImage, bool bAbsoluteValue=true)
Filters a CByteImage with the SobelY operator and writes the result to a CShortImage.
Data structure for the representation of a 3D vector.
Data structure for the representation of 8-bit grayscale images and 24-bit RGB (or HSV) color images ...
int numberOfChannels
Number of channels per pixel.
bool GeneralFilter(const CByteImage *pInputImage, CByteImage *pOutputImage, const int *pKernel, int nMaskSize, int nDivider=1, bool bAbsoluteValue=false)
Applies a user defined filter to a CByteImage and writes the result to a CByteImage.
bool CalculateHSVImage(const CByteImage *pInputImage, CByteImage *pOutputImage, const MyRegion *pROI=0)
Computes the HSV image for a RGB CByteImage and writes the result to a CByteImage.
int GetAreaSumNoChecks(const CIntImage *pIntegralImage, int min_x, int min_y, int max_x, int max_y)
Efficiently computes the sum of all pixel values in a rectangular area using integral image lookups...
bool HighPassY3(const CFloatMatrix *pInputImage, CFloatMatrix *pOutputImage)
Applies a 3x1 highpass filter to a CFloatMatrix and writes the result to a CFloatMatrix.
bool CalculateGradientImage(const CByteImage *pInputImage, CByteImage *pOutputImage)
Applies a combined simple gradient filter for both x- and y-direction to a CByteImage and stores the ...
bool Xor(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Applies the bitwise operator XOR to two instance of CByteImage and writes the result to a CByteImage...
#define OPTIMIZED_FUNCTION_HEADER_2(name, p1, p2)
bool CalculateHarrisMap(const CByteImage *pInputImage, CIntImage *pOutputImage)
Calculates the Harris cornerness measure for every pixel in a CByteImage and writes the results to a ...
GLuint GLuint GLsizei GLenum type
unsigned char * pixels
The pointer to the the pixels.
bool CalculateReverseSummedAreaTable(const CIntImage *pSummedAreaTable, CByteImage *pOutputImage)
Reconstructs the original image, given a summed area table, and writes the result to a grayscale CByt...
bool ConvertImage(const CByteImage *pInputImage, CByteImage *pOutputImage, bool bFast=false, const MyRegion *pROI=0)
Converts a grayscale CByteImage to an RGB CByteImage image and vice versa.
bool ThresholdBinarizeInverse(const CByteImage *pInputImage, CByteImage *pOutputImage, unsigned char nThreshold)
Performs inverse threshold binarization to a CByteImage and writes the result to a CByteImage...
int width
The width of the image in pixels.
std::vector< Vec3d > Vec3dList
float radius
The radius of the circle.
void DrawLinePolar(CByteImage *pImage, float theta, float r, int color_r, int color_g, int color_b, int thickness=1)
Draws a straight line into a CByteImage, given its parameters in polar form.
Vec2d normalVector
The normalized normal vector of the straight line.
bool FlipY(const CByteImage *pInputImage, CByteImage *pOutputImage)
Flips the rows in a CByteImage vertically and writes the result to a CByteImage.
bool SubtractWithSaturation(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Sets each pixel in a CByteImage to the difference between the corresponding pixels in two instances o...
int RegionGrowing(const CByteImage *pInputImage, MyRegion &resultRegion, int x, int y, int nMinimumPointsPerRegion=0, int nMaximumPointsPerRegion=0, bool bCalculateBoundingBox=true, bool bStorePixels=false)
Performs a region growing on a binary CByteImage on the basis of one seed point and stores the comput...
bool GaussianSmooth(const CByteImage *pInputImage, CFloatMatrix *pOutputImage, float fVariance, int nKernelSize)
Applies a Gaussian filter to a CByteImage and writes the result to a CFloatMatrix.
bool Average(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Sets each pixel in a CByteImage to the average of the corresponding pixels in two instances of CByteI...
int height
The height of the image in pixels.
std::vector< MyRegion > RegionList
bool DetermineAffineTransformation(const Vec2d *pSourcePoints, const Vec2d *pTargetPoints, int nPoints, Mat3d &A, bool bUseSVD=false)
Determines an affine transformation based on a set of 2d-2d point correspondences.
#define OPTIMIZED_FUNCTION_HEADER_5_RET(name, p1, p2, p3, p4, p5)
bool AverageFilter(const CByteImage *pInputImage, CByteImage *pOutputImage, int nMaskSize=3)
Applies an average filter to a CByteImage and writes the result to a CByteImage.
static const int MatrixGaussian5x5[25]
void DrawCircle(CByteImage *pImage, float mx, float my, float radius, int r=255, int g=255, int b=255, int thickness=1, bool bAntiAlias=false)
Draws a circle into a CByteImage.
GLsizei const GLfloat * value
bool CopyMatrix(const CFloatMatrix *pInputImage, CFloatMatrix *pOutputImage)
Copies one CFloatMatrix to another.
Data structure for the representation of a matrix of values of the data type float.
GLsizei GLsizei GLenum GLenum const GLvoid * data
bool AbsoluteDifference(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Sets each pixel in a CByteImage to the absolute value of the difference between the corresponding pix...
bool Canny(const CByteImage *pInputImage, CByteImage *pOutputImage, int nLowThreshold, int nHighThreshold)
Applies the Canny edge detector to a CByteImage and writes the result to a CByteImage.
bool CopyImage(const CByteImage *pInputImage, CByteImage *pOutputImage, const MyRegion *pROI=0, bool bUseSameSize=false)
Copies one CByteImage to another.
void NormalizeVec(Vec2d &vec)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
void ZeroFrame(CByteImage *pImage)
Sets all pixels on a one pixel wide frame of a CByteImage to zero.
bool Min(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Sets each pixel in a CByteImage to the minimum of the corresponding pixels in two instances of CByteI...
Data structure for the representation of single channel images of the data type signed short...
#define OPTIMIZED_FUNCTION_FOOTER
GLubyte GLubyte GLubyte a
int height
The height of the image in pixels.
bool Subtract(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Sets each pixel in a CByteImage to the difference between the corresponding pixels in two instances o...
float CalculateColorProbability(const Vec3d &rgb)
bool Amplify(const CByteImage *pInputImage, CByteImage *pOutputImage, float fFactor)
Multiplies each byte value of a CByteImage with a floating point factor and writes the result to a CB...
void DrawLine(CByteImage *pImage, const PointPair2d &line, int r=255, int g=255, int b=255, int thickness=1)
Draws a line segment into a CByteImage, given its two end points.
bool PrewittY(const CByteImage *pInputImage, CShortImage *pOutputImage, bool bAbsoluteValue=true)
Filters a CByteImage with the PrewittY operator and writes the result to a CShortImage.
bool ThresholdBinarize(const CByteImage *pInputImage, CByteImage *pOutputImage, unsigned char nThreshold)
Performs threshold binarization to a CByteImage and writes the result to a CByteImage.
static bool Dilate3x3(const CByteImage *pInputImage, CByteImage *pOutputImage, const MyRegion *pROI)
#define OPTIMIZED_FUNCTION_HEADER_8_ROI(name, p1, p2, p3, p4, p5, p6, p7, p8, p9)
int bytesPerPixel
The number of bytes used for encoding one pixel.
static const int division_table[]
#define OPTIMIZED_FUNCTION_HEADER_2_ROI(name, p1, p2, p3)
GLenum GLsizei GLsizei height
ImageType
Enum specifying the supported image types.
bool CalculateGradientImageBinary(const CByteImage *pInputImage, CByteImage *pOutputImage)
Calculates a gradient image for a CByteImage and writes the result to a CByteImage, for the special case of binary images.
bool Rotate(const CByteImage *pInputImage, CByteImage *pOutputImage, float mx, float my, float theta, bool bInterpolation=true)
Rotates pInputImage to the dimensions specified by pOutputImage and stores the result in pOutputImage...
bool FilterHSV2(const CByteImage *pInputImage, CByteImage *pOutputImage, unsigned char min_hue, unsigned char max_hue, unsigned char min_sat, unsigned char max_sat, unsigned char min_v, unsigned char max_v, const MyRegion *pROI=0)
Performs color filtering with binarization for an HSV CByteImage and writes the result to a grayscale...
bool Spread(const CByteImage *pInputImage, CByteImage *pOutputImage)
Performs a spread operation on pInputImage and stores the result in pOutputImage. ...
bool Rotate180Degrees(const CByteImage *pInputImage, CByteImage *pOutputImage)
Rotates a CByteImage by 180 degrees and writes the result to a CByteImage.
bool Add(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Sets each pixel in a CByteImage to the sum of the corresponding pixels in two instances of CByteImage...
Data structure for the representation of a 2D straight line.
static void track(unsigned char *magnitudes, int *stack, int offset, int width)
GLenum GLenum GLenum input
ImageType type
The type of the image.
bool Laplace1(const CByteImage *pInputImage, CShortImage *pOutputImage, bool bAbsoluteValue=true)
Filters a CByteImage with the Laplace1 operator and writes the result to a CShortImage.
bool GaussianSmooth5x5(const CFloatMatrix *pInputImage, CFloatMatrix *pOutputImage, float fVariance)
Applies a 5x5 Gaussian filter to a CFloatMatrix and writes the result to a CFloatMatrix.
GLdouble GLdouble GLdouble r
Vec2d center
The center of the circle.
bool AdaptFrame(const CByteImage *pInputImage, CByteImage *pOutputImage)
Sets all pixels on a one pixel wide outer frame in a CByteImage to the pixel values of the inner fram...
int CalculateHarrisInterestPoints(const CByteImage *pInputImage, Vec2d *pInterestPoints, int nMaxPoints, float fQualityLevel=0.01f, float fMinDistance=5.0f)
Computes interest points within a CByteImage by applying the Harris corner detector.
float c
The negative scalar product of normalVector and point.
void AddElement(const T &element)
int GetAreaSum(const CIntImage *pIntegralImage, int min_x, int min_y, int max_x, int max_y)
Efficiently computes the sum of all pixel values in a rectangular area using integral image lookups...
Data structure for the representation of a 2D vector.
bool Erode(const CByteImage *pInputImage, CByteImage *pOutputImage, int nMaskSize=3, const MyRegion *pROI=0)
Applies a morphological erode operation to a binary CByteImage and writes the result to a binary CByt...
bool HoughTransformCircles(const CByteImage *pImage, CByteImage *pVisualizationImage, Vec3dList &resultCircles, int rmin, int rmax, int nCirclesToExtract, int nMinHits=1)
Performs the Hough transform for circles on a CByteImage.
bool Or(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Applies the bitwise operator OR to two instance of CByteImage and writes the result to a CByteImage...
bool HistogramStretching(const CByteImage *pInputImage, CByteImage *pOutputImage, float p1=0.1f, float p2=0.9f)
Performs histogram stretching on pInputImage and stores the result in pOutputImage.
Data structure for the representation of single channel images of the data type signed int...
Data structure for the representation of a matrix of values of the data type double.
static bool Erode3x3(const CByteImage *pInputImage, CByteImage *pOutputImage, const MyRegion *pROI)
bool HistogramEqualization(const CByteImage *pInputImage, CByteImage *pOutputImage)
Performs histogram equalization for a CByteImage and writes the result to a CByteImage.
void SetVec(Vec2d &vec, float x, float y)
bool And(const CByteImage *pInputImage1, const CByteImage *pInputImage2, CByteImage *pOutputImage)
Applies the bitwise operator AND to two instance of CByteImage and writes the result to a CByteImage...
#define OPTIMIZED_FUNCTION_HEADER_3_ROI(name, p1, p2, p3, p4)
bool CalculateSummedAreaTable(const CByteImage *pInputImage, CIntImage *pSummedAreaTable)
Calculates the summed area table of a grayscale CByteImage and writes the result to a CIntImage...
bool GaussianSmooth3x3(const CByteImage *pInputImage, CByteImage *pOutputImage)
Applies a 3x3 Gaussian filter to a CByteImage and writes the result to a CByteImage.
void Zero(CByteImage *pImage, const MyRegion *pROI=0)
Sets all values in a CByteImage to zero.
bool ConvertMatrix(const CFloatMatrix *pInputImage, CDoubleMatrix *pOutputImage)
Converts a CFloatMatrix to a CDoubleMatrix.
bool CalculateGradientImagePrewitt(const CByteImage *pInputImage, CByteImage *pOutputImage)
Applies a combined Prewitt filter for both x- and y-direction to a CByteImage and stores the result i...
static float sin_table_[380]
Data structure for the representation of a 3x3 matrix.
static float cos_table_[380]
GLubyte GLubyte GLubyte GLubyte w
Data structure for the representation of any image type (arbitrary number of channels) using the data...
Training and application of an RGB color model on the basis of the Mahalanobis distance.
#define OPTIMIZED_FUNCTION_HEADER_5(name, p1, p2, p3, p4, p5)
static int _RegionGrowing(unsigned char *pixels, int width, int offset, int *stack, int *region, MyRegion &resultRegion, int nMinimumPointsPerRegion, int nMaximumPointsPerRegion, bool bCalculateBoundingBox)
bool Resize(const CByteImage *pInputImage, CByteImage *pOutputImage, const MyRegion *pROI=0, bool bInterpolation=true)
Resizes a CByteImage and writes the result to a CByteImage.
static bool AverageFilter3x3(const CByteImage *pInputImage, CByteImage *pOutputImage)
bool FilterHSV(const CByteImage *pInputImage, CByteImage *pOutputImage, unsigned char hue, unsigned char tol_hue, unsigned char min_sat, unsigned char max_sat, unsigned char min_v, unsigned char max_v, const MyRegion *pROI=0)
Performs color filtering with binarization for an HSV CByteImage and writes the result to a grayscale...
static void InitSinCosTables()
bool CalculateIntegralImage(const CByteImage *pInputImage, CIntImage *pIntegralImage)
Calculates the integral image of a grayscale CByteImage and writes the result to a CIntImage...