38 #include <visp3/core/vpImageMorphology.h>
40 #if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2)
41 # include <emmintrin.h>
42 # define VISP_HAVE_SSE2 1
70 std::cerr <<
"Input image is empty!" << std::endl;
74 const unsigned char null_value = 255;
78 for (
unsigned int i = 0; i < J.getHeight(); i++) {
79 if (i == 0 || i == J.getHeight() - 1) {
80 for (
unsigned int j = 0; j < J.getWidth(); j++) {
85 memcpy(J[i]+1, I[i-1],
sizeof(
unsigned char)*I.
getWidth());
86 J[i][J.getWidth() - 1] = null_value;
91 unsigned int offset[5] = {1, J.
getWidth(), J.getWidth()+1, J.getWidth()+2, J.getWidth()*2 + 1};
93 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
95 unsigned char *ptr_curr_J = J.bitmap + i*J.getWidth();
101 for (; j <= I.
getWidth() - 16; j+=16) {
102 __m128i m = _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[0]) );
103 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[1])) );
104 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[2])) );
105 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[3])) );
106 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[4])) );
108 _mm_storeu_si128( (__m128i *) (ptr_curr_I + j), m );
114 unsigned char min_value = null_value;
115 for (
int k = 0; k < 5; k++) {
116 min_value = std::min(min_value, *(ptr_curr_J + j + offset[k]));
119 *(ptr_curr_I + j) = min_value;
124 unsigned int offset[9] = {0, 1, 2, J.getWidth(), J.getWidth()+1, J.getWidth()+2,
125 J.getWidth()*2, J.getWidth()*2 + 1, J.getWidth()*2 + 2};
127 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
129 unsigned char *ptr_curr_J = J.bitmap + i*J.getWidth();
135 for (; j <= I.
getWidth() - 16; j+=16) {
136 __m128i m = _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[0]) );
137 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[1])) );
138 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[2])) );
139 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[3])) );
140 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[4])) );
141 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[5])) );
142 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[6])) );
143 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[7])) );
144 m = _mm_min_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[8])) );
146 _mm_storeu_si128( (__m128i *) (ptr_curr_I + j), m );
152 unsigned char min_value = null_value;
153 for (
int k = 0; k < 9; k++) {
154 min_value = std::min(min_value, *(ptr_curr_J + j + offset[k]));
157 *(ptr_curr_I + j) = min_value;
187 std::cerr <<
"Input image is empty!" << std::endl;
191 const unsigned char null_value = 0;
195 for (
unsigned int i = 0; i < J.getHeight(); i++) {
196 if (i == 0 || i == J.getHeight() - 1) {
197 for (
unsigned int j = 0; j < J.getWidth(); j++) {
198 J[i][j] = null_value;
201 J[i][0] = null_value;
202 memcpy(J[i]+1, I[i-1],
sizeof(
unsigned char)*I.
getWidth());
203 J[i][J.getWidth() - 1] = null_value;
208 unsigned int offset[5] = {1, J.
getWidth(), J.getWidth()+1, J.getWidth()+2, J.getWidth()*2 + 1};
210 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
212 unsigned char *ptr_curr_J = J.bitmap + i*J.getWidth();
218 for (; j <= I.
getWidth() - 16; j+=16) {
219 __m128i m = _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[0]) );
220 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[1])) );
221 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[2])) );
222 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[3])) );
223 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[4])) );
225 _mm_storeu_si128( (__m128i *) (ptr_curr_I + j), m );
231 unsigned char max_value = null_value;
232 for (
int k = 0; k < 5; k++) {
233 max_value = std::max(max_value, *(ptr_curr_J + j + offset[k]));
236 *(ptr_curr_I + j) = max_value;
241 unsigned int offset[9] = {0, 1, 2, J.getWidth(), J.getWidth()+1, J.getWidth()+2,
242 J.getWidth()*2, J.getWidth()*2 + 1, J.getWidth()*2 + 2};
244 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
246 unsigned char *ptr_curr_J = J.bitmap + i*J.getWidth();
252 for (; j <= I.
getWidth() - 16; j+=16) {
253 __m128i m = _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[0]) );
254 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[1])) );
255 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[2])) );
256 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[3])) );
257 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[4])) );
258 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[5])) );
259 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[6])) );
260 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[7])) );
261 m = _mm_max_epu8(m, _mm_loadu_si128( (
const __m128i *) (ptr_curr_J + j + offset[8])) );
263 _mm_storeu_si128( (__m128i *) (ptr_curr_I + j), m );
269 unsigned char max_value = null_value;
270 for (
int k = 0; k < 9; k++) {
271 max_value = std::max(max_value, *(ptr_curr_J + j + offset[k]));
274 *(ptr_curr_I + j) = max_value;
static void dilatation(vpImage< Type > &I, Type value, Type value_out, vpConnexityType connexity=CONNEXITY_4)
unsigned int getWidth() const
Type * bitmap
points toward the bitmap
static void erosion(vpImage< Type > &I, Type value, Type value_out, vpConnexityType connexity=CONNEXITY_4)
unsigned int getSize() const
unsigned int getHeight() const