关于二进制位运算的原理性介绍,很多入门级的c语言书籍或者博客上都已经介绍得非常详细。本文不打算从入门原理重走老路,准备从应用角度出发,持续性介绍关于二进制位运算在实际应用中的巧妙性,给自己的学习作一个记录,同时也分享给爱好编程的朋友,一起交流分享。本文将主要介绍关于二进制位运算在图像处理算法等基础算法方面的巧妙应用,希望同样有巧妙应用的你,将你的奇思妙想留言到本文结尾,当然更希望能直接的与你一起探讨、学习,有好的东西分享或者疑问,请mail我:cimage1987@163.com
(一)位运算在数字图像处理中的奇思妙想之快速计算最小最大灰度级
从原理上说,一幅灰度图像的理论像素值分布可能取值范围是[0, 255],共256个灰度级,但是在实际图像中,并不一定占据整个256个灰度级,有可能灰度分布在[50, 200]之间等等。由于后续算法处理的需求,我们需要提前统计计算图像的实际灰度级分布范围,也可能由于直方图均衡化的需要,提前计算图像的最小、最大灰度级。因此,我们可能会写下如下的代码(结合OpenCV):
void LocalMaxMinPixel(cv::Mat _img, int *MinValue, int *MaxValue) { int wIndex = 0, hIndex = 0, position = 0; unsigned char min = 255, max = 0, tempValue = 0; int width = _img.cols, height = _img.rows; for( hIndex = 0; hIndex < height; hIndex++) { for( wIndex = 0; wIndex < width; wIndex++, position++) { tempValue = _img.data[position]; if(tempValue < min) min = tempValue;//最小灰度级 if (tempValue > max) max = tempValue;//最大灰度级 } } *MinValue = min; *MaxValue = max; }
从上述代码中,可以很直观的发现,对整个图像遍历,每次都需要进行2次判断,或许还要进行2次赋值操作。那么,如果运用位运算替代,这里可以很巧妙的替换掉两次判定操作,仅进行两次位运算处理,具体代码如下:
void LocalMaxMinPixel(cv::Mat _img, int *MinValue, int *MaxValue) { int wIndex = 0, hIndex = 0, position = 0; unsigned char min = 255, max = 0; int width = _img.cols, height = _img.rows; for( hIndex = 0; hIndex < height; hIndex++) { for( wIndex = 0; wIndex < width; wIndex++, position++) { min &= _img.data[position];//最小灰度级 max |= _img.data[position];//最大灰度级 } } *MinValue = min; *MaxValue = max; }