又是每周一次的坑爹OPENCV!加油奧里給!
1、圖像縮放——直接調用函數操作
Mat img = imread("E:/lena.jpg"); int img_cols = img.cols * 0.5; int img_rows = img.cols * 0.5; Mat change = Mat::zeros(img_cols,img_rows,CV_8UC3); resize(img, change, change.size()); imshow("change",change); waitKey(0); return 0;
作用是縮放為原本圖像的1/2,來看效果圖
姑且命名為大lena和小lena。
2、圖像縮放——自己動手寫,最近鄰域插值法
原理:
目標上的每一個點都來自於原圖像
newX= x*(src 行/目標 ) newX =1*(10/5)=2
newY= y*(src 列/目標 ) newY =1*(10/5)=2
12.3 -> 12
(以下內容轉載自http://ddrv.cn/a/114636)
void nearestIntertoplation(cv::Mat& src, cv::Mat& dst, const int rows, const int cols) { //比例尺 const double scale_row = static_cast<double>(src.rows) / rows; const double scale_col = static_cast<double>(src.rows) / cols; //擴展src到dst dst = cv::Mat(rows, cols, src.type()); assert(src.channels() == 1 && dst.channels() == 1); for (int i = 0; i < rows; ++i)//dst的行 for (int j = 0; j < cols; ++j)//dst的列 { //求插值的四個點 double y = (i + 0.5) * scale_row + 0.5; double x = (j + 0.5) * scale_col + 0.5; int x1 = static_cast<int>(x);//col對應x if (x1 >= (src.cols - 2)) x1 = src.cols - 2;//防止越界 int x2 = x1 + 1; int y1 = static_cast<int>(y);//row對應y if (y1 >= (src.rows - 2)) y1 = src.rows - 2; int y2 = y1 + 1; //根據目標圖像的像素點(浮點坐標)找到原始圖像中的4個像素點,取距離該像素點最近的一個原始像素值作為該點的值。 assert(0 < x2 && x2 < src.cols && 0 < y2 && y2 < src.rows); std::vector<double> dist(4); dist[0] = distance(x, y, x1, y1); dist[1] = distance(x, y, x2, y1); dist[2] = distance(x, y, x1, y2); dist[3] = distance(x, y, x2, y2); int min_val = dist[0]; int min_index = 0; for (int i = 1; i < dist.size(); ++i) if (min_val > dist[i]) { min_val = dist[i]; min_index = i; } switch (min_index) { case 0: dst.at<uchar>(i, j) = src.at<uchar>(y1, x1); break; case 1: dst.at<uchar>(i, j) = src.at<uchar>(y1, x2); break; case 2: dst.at<uchar>(i, j) = src.at<uchar>(y2, x1); break; case 3: dst.at<uchar>(i, j) = src.at<uchar>(y2, x2); break; default: assert(false); } } } double distance(const double x1, const double y1, const double x2, const double y2)//兩點之間距離,這里用歐式距離 { return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);//只需比較大小,返回距離平方即可 }
實驗結果如下
3、圖像裁切
cv::Mat img = cv::imread("E:/lena.jpg", 0); if (img.empty()) return -1; int col = img.cols; int row = img.rows; Rect rect(col * 1 / 4, col*1/2, row * 1 / 4, row*1/2); Mat image = img(rect); imshow("sb", image); waitKey(0); return 0;
最終結果
4、圖像的位移
cv::Mat img = cv::imread("E:/lena.jpg", 0); if (img.empty()) return -1; int col = img.cols; int row = img.rows; Mat dst; dst.create(row, col, img.type()); Vec3b* p; for (int i = 0; i < row; i++) { p = dst.ptr<Vec3b>(i); for (int j = 0; j < col; j++) { int x = j - 10; int y = i - 10; if (x >= 0 && y >= 0 && x < col && y < row) { img.at<cv::Vec3b>(i, j) = dst.ptr<cv::Vec3b>(y)[x]; } } } waitKey(0); return 0;