之前幾天搗鼓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

把相應的圖片放到同目錄的文件夾內,進入到該文件夾,輸入命令行
cmake .
make
./my_hw1
就可以執行了~~
最後貼上一個運行結果圖:
