【Opencv】图像扫描

来源:互联网 发布:淘宝条形码是什么意思 编辑:程序博客网 时间:2024/04/29 04:07

<span style="font-size:48px;color:#cc66cc;">ColorReduce</span>

void colorReduce(cv::Mat image, int div)  

彩色图像由三个通道像素组成(RGB),因此颜色总数为256*256*256。为了降低分析的复杂性,可以通过colorReduce函数把每种颜色数量减少8倍,则颜色总数变成32*32*32。因此基本的减色算法很简单,假设N是减色因子,则代码实现就是简单的value/N*N,可以得到N的倍数,并且刚好不超过原始像素值。只需加上N/2就得到相邻的N倍数之间的中间值。最后对所有8位通道值重复这个过程,就会得到(256/N)*(256/N)*(256/N)种可能的颜色值。


 

                                 (a)原始图像                                                                                            (b)ColorReduce64倍

方法一:.ptr和数组操作

<span style="background-color: rgb(255, 255, 255);"><span style="font-family:Times New Roman;font-size:18px;">void colorReduce1(cv::Mat &image, int div = 64) {    //64是减色因子int nl = image.rows; // number of linesint nc = image.cols * image.channels(); // total number of elements per linefor (int j = 0; j<nl; j++) {uchar* data = image.ptr<uchar>(j);//访问图像中一个行地址就用.ptrfor (int i = 0; i<nc; i++) {// process each pixel ---------------------data[i] = data[i] / div*div + div / 2;// end of pixel processing ----------------} // end of line                   }}</span></span>

方法二:.ptr和指针操作*++

<span style="font-family:Times New Roman;font-size:18px;">void colorReduce2(cv::Mat &image, int div = 64) {int nl = image.rows; // number of linesint nc = image.cols * image.channels(); // total number of elements per linefor (int j = 0; j<nl; j++) {uchar* data = image.ptr<uchar>(j);for (int i = 0; i<nc; i++) {// process each pixel ---------------------*data++ = *data / div*div + div / 2;// end of pixel processing ----------------} // end of line                   }}</span>


方法三:.ptr,指针操作*++和位运算
<span style="font-family:Times New Roman;font-size:18px;">void colorReduce3(cv::Mat &image, int div = 64) {int nl = image.rows; // number of linesint nc = image.cols * image.channels(); // total number of elements per lineint n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));// mask used to round the pixel valueuchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0for (int j = 0; j<nl; j++) {uchar* data = image.ptr<uchar>(j);for (int i = 0; i<nc; i++) {// process each pixel ---------------------*data++ = *data&mask + div / 2;// end of pixel processing ----------------} // end of line                   }}</span>

方法四:Mat迭代器

<span style="font-family:Times New Roman;font-size:18px;">void colorReduce4(cv::Mat &image, int div = 64) {// get iteratorscv::Mat_<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>();cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>();for (; it != itend; ++it) {// process each pixel ---------------------(*it)[0] = (*it)[0] / div*div + div / 2;(*it)[1] = (*it)[1] / div*div + div / 2;(*it)[2] = (*it)[2] / div*div + div / 2;// end of pixel processing ----------------}}</span>

方法五:.at 图像坐标
<span style="font-family:Times New Roman;font-size:18px;font-weight: normal;">void colorReduce5(cv::Mat &image, int div = 64) {int nl = image.rows; // number of linesint nc = image.cols; // number of columnsfor (int j = 0; j<nl; j++) {for (int i = 0; i<nc; i++) {// process each pixel ---------------------image.at<cv::Vec3b>(j, i)[0] = image.at<cv::Vec3b>(j, i)[0] / div*div + div / 2;image.at<cv::Vec3b>(j, i)[1] = image.at<cv::Vec3b>(j, i)[1] / div*div + div / 2;image.at<cv::Vec3b>(j, i)[2] = image.at<cv::Vec3b>(j, i)[2] / div*div + div / 2;// end of pixel processing ----------------} // end of line                   }}</span>

方法六:创建输出图像

<pre name="code" class="cpp"><span style="font-family:Times New Roman;font-size:18px;font-weight: normal;">void colorReduce6(const cv::Mat &image, // input image cv::Mat &result,      // output imageint div = 64) {int nl = image.rows; // number of linesint nc = image.cols; // number of columns// allocate output image if necessaryresult.create(image.rows, image.cols, image.type());// created images have no padded pixelsnc = nc*nl;nl = 1;  // it is now a 1D arrayint n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));// mask used to round the pixel valueuchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0for (int j = 0; j<nl; j++) {uchar* data = result.ptr<uchar>(j);const uchar* idata = image.ptr<uchar>(j);for (int i = 0; i<nc; i++) {// process each pixel ---------------------*data++ = (*idata++)&mask + div / 2;*data++ = (*idata++)&mask + div / 2;*data++ = (*idata++)&mask + div / 2;// end of pixel processing ----------------} // end of line                   }}</span>

方法七:重载操作

<span style="font-family:Times New Roman;font-size:18px;font-weight: normal;">void colorReduce7(cv::Mat &image, int div = 64) {int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));// mask used to round the pixel valueuchar mask = 0xFF << n; // e.g. for div=16, mask= 0xF0// perform color reductionimage = (image&cv::Scalar(mask, mask, mask)) + cv::Scalar(div / 2, div / 2, div / 2);}</span>






 

     


























0 0
原创粉丝点击