【OpenCV】像素操作的数字图像处理
之前几天捣鼓matlab,用来处理数字图像,矩阵操作什么的,如果忘记线性代数就真的GG了。
在用了matlab被深深地吐槽之后,决定改用opencv,C++貌似也是处理数字图像的很好的工具
1. 在ubuntu上安装opencv
教程可以百度之,都很详细的
2. 像素处理图像:
(1)根据输入的数据,用邻近取样插值法,缩放图像
邻近取样插值法原理:http://blog.chinaunix.net/uid-27675161-id-3452025.html
(2)根据输入,改变数字图像的灰度分辨率
(3)此次实验操作用灰度图来实现
3. 直接贴代码+注释吧
1 //my_hw1.cpp 2 #include <stdio.h> 3 #include<iostream> 4 #include <opencv2/opencv.hpp> 5 #include<opencv2/core/core.hpp> 6 #include<opencv2/highgui/highgui.hpp> 7 8 using namespace cv; 9 using namespace std; 10 11 string my_pic = "07.png"; 12 Mat image = imread(my_pic, CV_LOAD_IMAGE_GRAYSCALE); 13 14 void on_trackbar(int p, void*) { 15 16 //************************Scale*************************** 17 //每次回调都重新载入图像 18 Mat src = imread(my_pic, CV_LOAD_IMAGE_GRAYSCALE); 19 20 //获取三个滑动条的值 21 int c = cvGetTrackbarPos("Width", "after change"); 22 int r = cvGetTrackbarPos("Height", "after change"); 23 int level = cvGetTrackbarPos("Level", "after change"); 24 25 //记录原始图的宽高,以及对应的点sx,sy(邻近取样插值法中用到) 26 int sh = src.rows; 27 int sw = src.cols; 28 int sx, sy; 29 30 //重置后的新图片 31 Mat dst(r, c, src.type()); 32 33 //填充新图片的像素 34 for (int i = 0; i < r; i ++) { 35 for (int j = 0; j < c; j ++) { 36 double x = i / (r + 0.0); 37 double y = j / (c + 0.0); 38 sx = sh * x; 39 sy = sw * y; 40 dst.at<uchar>(i, j) = src.at<uchar>(sx,sy); 41 } 42 } 43 44 //********************Quantization************************ 45 46 //使得level的值合法 47 if (level <= 256 && level >= 128)level = 128; 48 else if(level < 128 && level >= 64)level = 64; 49 else if(level < 64 && level >= 32)level = 32; 50 else if(level < 32 && level >= 16) level = 16; 51 else if(level < 16 && level >= 8)level = 8; 52 else if(level < 8 && level >= 4)level = 4; 53 else level = 2; 54 55 int channels = dst.channels(); 56 int nrows = dst.rows; 57 int ncols = dst.cols * channels; 58 59 uchar table[256]; 60 int degree = 255/(level - 1); 61 int number = 256 / level; 62 int count = 0; 63 int value = 0; 64 65 //设定好要求的灰度映射 66 for (int i = 0; i < 256; i ++, count ++) { 67 if (count < number) table[i] = value; 68 else { 69 count = 0; 70 value += degree; 71 table[i] = value; 72 } 73 } 74 75 if (src.isContinuous()) { 76 ncols *= nrows; 77 nrows = 1; 78 } 79 80 for (int i = 0; i < nrows; i ++) { 81 uchar *p = dst.ptr<uchar>(i); 82 for (int j = 0; j < ncols; j ++) { 83 p[j] = table[p[j]]; 84 } 85 } 86 87 //cout << level << " " << c << " " << r << "\n"; 88 imshow("after change", dst); 89 } 90 91 int main( int argc, char** argv) { 92 imshow("before change", image); 93 94 int width = 384; 95 int height = 256; 96 int level = 256; 97 namedWindow("after change", CV_WINDOW_AUTOSIZE); 98 createTrackbar( "Width", "after change", &width, 800, on_trackbar); 99 createTrackbar( "Height", "after change", &height, 500, on_trackbar); 100 createTrackbar( "Level", "after change", &level, 256, on_trackbar); //slider 101 102 on_trackbar(0, 0); 103 104 waitKey(); 105 return 0; 106 } 107
另外,我选择的编译方式是cmake + make;
CMakeLists.txt
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 cmake_minimum_required(VERSION 2.8) 2 project( my_hw1 ) 3 find_package( OpenCV REQUIRED ) 4 add_executable( my_hw1 my_hw1.cpp ) 5 target_link_libraries( my_hw1 ${OpenCV_LIBS} )
把相应的图片放到同目录的文件夹内,进入到该文件夹,输入命令行
cmake .
make
./my_hw1
就可以执行了~~
最后贴上一个运行结果图: