Opencv二值化可以说是最简单的算子了,只要设定阈值,再根据相应的规则对于像素赋值为0或255即可
普通的C++代码应该不用在解释,这里贴入Opencv的二值化带SSE代码
for( int i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { for( j = 0; j <= roi.width - v_uint8::nlanes; j += v_uint8::nlanes) { v_uint8 v0; v0 = vx_load( src + j ); v0 = thresh_u < v0; v0 = v0 & maxval16; v_store( dst + j, v0 ); } }
这里的v_uint8 在SSE中就是__m128i,vx_load就是_mm_loadu_si128,v_store 就是_mm_storeu_si128,并且还对等于,大于等做了重载
#define OPENCV_HAL_IMPL_SSE_INT_CMP_OP(_Tpuvec, _Tpsvec, suffix, sbit) \ inline _Tpuvec operator == (const _Tpuvec& a, const _Tpuvec& b) \ { return _Tpuvec(_mm_cmpeq_##suffix(a.val, b.val)); } \ inline _Tpuvec operator != (const _Tpuvec& a, const _Tpuvec& b) \ { \ __m128i not_mask = _mm_set1_epi32(-1); \ return _Tpuvec(_mm_xor_si128(_mm_cmpeq_##suffix(a.val, b.val), not_mask)); \ } \ inline _Tpsvec operator == (const _Tpsvec& a, const _Tpsvec& b) \ { return _Tpsvec(_mm_cmpeq_##suffix(a.val, b.val)); } \ inline _Tpsvec operator != (const _Tpsvec& a, const _Tpsvec& b) \ { \ __m128i not_mask = _mm_set1_epi32(-1); \ return _Tpsvec(_mm_xor_si128(_mm_cmpeq_##suffix(a.val, b.val), not_mask)); \ } \ inline _Tpuvec operator < (const _Tpuvec& a, const _Tpuvec& b) \ { \ __m128i smask = _mm_set1_##suffix(sbit); \ return _Tpuvec(_mm_cmpgt_##suffix(_mm_xor_si128(b.val, smask), _mm_xor_si128(a.val, smask))); \ } \ inline _Tpuvec operator > (const _Tpuvec& a, const _Tpuvec& b) \ { \ __m128i smask = _mm_set1_##suffix(sbit); \ return _Tpuvec(_mm_cmpgt_##suffix(_mm_xor_si128(a.val, smask), _mm_xor_si128(b.val, smask))); \ } \ inline _Tpuvec operator <= (const _Tpuvec& a, const _Tpuvec& b) \ { \ __m128i smask = _mm_set1_##suffix(sbit); \ __m128i not_mask = _mm_set1_epi32(-1); \ __m128i res = _mm_cmpgt_##suffix(_mm_xor_si128(a.val, smask), _mm_xor_si128(b.val, smask)); \ return _Tpuvec(_mm_xor_si128(res, not_mask)); \ } \ inline _Tpuvec operator >= (const _Tpuvec& a, const _Tpuvec& b) \ { \ __m128i smask = _mm_set1_##suffix(sbit); \ __m128i not_mask = _mm_set1_epi32(-1); \ __m128i res = _mm_cmpgt_##suffix(_mm_xor_si128(b.val, smask), _mm_xor_si128(a.val, smask)); \ return _Tpuvec(_mm_xor_si128(res, not_mask)); \ } \ inline _Tpsvec operator < (const _Tpsvec& a, const _Tpsvec& b) \ { \ return _Tpsvec(_mm_cmpgt_##suffix(b.val, a.val)); \ } \ inline _Tpsvec operator > (const _Tpsvec& a, const _Tpsvec& b) \ { \ return _Tpsvec(_mm_cmpgt_##suffix(a.val, b.val)); \ } \ inline _Tpsvec operator <= (const _Tpsvec& a, const _Tpsvec& b) \ { \ __m128i not_mask = _mm_set1_epi32(-1); \ return _Tpsvec(_mm_xor_si128(_mm_cmpgt_##suffix(a.val, b.val), not_mask)); \ } \ inline _Tpsvec operator >= (const _Tpsvec& a, const _Tpsvec& b) \ { \ __m128i not_mask = _mm_set1_epi32(-1); \ return _Tpsvec(_mm_xor_si128(_mm_cmpgt_##suffix(b.val, a.val), not_mask)); \ }