-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathconvertcolor.cpp
139 lines (115 loc) · 4.25 KB
/
convertcolor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "skeleton_filter.hpp"
#if defined __SSSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
# include "tmmintrin.h"
# define HAVE_SSE
#endif
#include <string>
#include <sstream>
// Function for debug prints
template <typename T>
std::string __m128i_toString(const __m128i var)
{
std::stringstream sstr;
const T* values = (const T*) &var;
if (sizeof(T) == 1)
{
for (unsigned int i = 0; i < sizeof(__m128i); i++)
{
sstr << (int) values[i] << " ";
}
}
else
{
for (unsigned int i = 0; i < sizeof(__m128i) / sizeof(T); i++)
{
sstr << values[i] << " ";
}
}
return sstr.str();
}
void ConvertColor_BGR2GRAY_BT709(const cv::Mat& src, cv::Mat& dst)
{
CV_Assert(CV_8UC3 == src.type());
cv::Size sz = src.size();
dst.create(sz, CV_8UC1);
const int bidx = 0;
for (int y = 0; y < sz.height; y++)
{
const cv::Vec3b *psrc = src.ptr<cv::Vec3b>(y);
uchar *pdst = dst.ptr<uchar>(y);
for (int x = 0; x < sz.width; x++)
{
float color = 0.2126 * psrc[x][2-bidx] + 0.7152 * psrc[x][1] + 0.0722 * psrc[x][bidx];
pdst[x] = (int)(color + 0.5);
}
}
}
void ConvertColor_BGR2GRAY_BT709_fpt(const cv::Mat& src, cv::Mat& dst)
{
CV_Assert(CV_8UC3 == src.type());
cv::Size sz = src.size();
dst.create(sz, CV_8UC1);
const int bidx = 0;
int C1 = 13933;
int C2 = 46871;
int C3 = 4732;
int C4 = 32768;
/*short C1 = 435;
short C2 = 1465;
short C3 = 148;
short C4 = 1024;*/
for (int y = 0; y < sz.height; y++)
{
const cv::Vec3b *psrc = src.ptr<cv::Vec3b>(y);
uchar *pdst = dst.ptr<uchar>(y);
for (int x = 0; x < sz.width; x++)
{
int color = C1 * psrc[x][2-bidx] + C2 * psrc[x][1] + C3 * psrc[x][bidx];
pdst[x] = (int)(color + C4) * 0.0000152587890625;
}
}
}
void ConvertColor_BGR2GRAY_BT709_simd(const cv::Mat& src, cv::Mat& dst)
{
CV_Assert(CV_8UC3 == src.type());
cv::Size sz = src.size();
dst.create(sz, CV_8UC1);
#ifdef HAVE_SSE
// __m128i ssse3_blue_indices_0 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, 12, 9, 6, 3, 0);
// __m128i ssse3_blue_indices_1 = _mm_set_epi8(-1, -1, -1, -1, -1, 14, 11, 8, 5, 2, -1, -1, -1, -1, -1, -1);
// __m128i ssse3_blue_indices_2 = _mm_set_epi8(13, 10, 7, 4, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
// __m128i ssse3_green_indices_0 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13, 10, 7, 4, 1);
// __m128i ssse3_green_indices_1 = _mm_set_epi8(-1, -1, -1, -1, -1, 15, 12, 9, 6, 3, 0, -1, -1, -1, -1, -1);
// __m128i ssse3_green_indices_2 = _mm_set_epi8(14, 11, 8, 5, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
__m128i ssse3_red_indices_0 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, 11, 8, 5, 2);
__m128i ssse3_red_indices_1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, 13, 10, 7, 4, 1, -1, -1, -1, -1, -1);
__m128i ssse3_red_indices_2 = _mm_set_epi8(15, 12, 9, 6, 3, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
#endif
for (int y = 0; y < sz.height; y++)
{
const uchar *psrc = src.ptr<uchar>(y);
uchar *pdst = dst.ptr<uchar>(y);
int x = 0;
#ifdef HAVE_SSE
// Here is 16 times unrolled loop for vector processing
for (; x <= sz.width - 16; x += 16)
{
__m128i chunk0 = _mm_loadu_si128((const __m128i*)(psrc + x*3 + 16*0));
__m128i chunk1 = _mm_loadu_si128((const __m128i*)(psrc + x*3 + 16*1));
__m128i chunk2 = _mm_loadu_si128((const __m128i*)(psrc + x*3 + 16*2));
__m128i red = _mm_or_si128(_mm_or_si128(_mm_shuffle_epi8(chunk0, ssse3_red_indices_0),
_mm_shuffle_epi8(chunk1, ssse3_red_indices_1)),
_mm_shuffle_epi8(chunk2, ssse3_red_indices_2));
/* ??? */
_mm_storeu_si128((__m128i*)(pdst + x), red);
}
#endif
// Process leftover pixels
for (; x < sz.width; x++)
{
/* ??? */
}
}
// ! Remove this before writing your optimizations !
ConvertColor_BGR2GRAY_BT709_fpt(src, dst);
}