图片插值

匿名 (未验证) 提交于 2019-12-03 00:40:02

实现部分图片插值算法(最近邻,双线性,双立方)

#include <iostream> #include <cmath> #include<highgui.h> #include <opencv2/core/mat.hpp> #include<opencv2/highgui/highgui.hpp> #include <opencv2/core/core.hpp> #include <opencv2/imgproc.hpp>  struct MyMat {     u_char *data;     int w, h, c;     MyMat(){}     MyMat(cv::Mat &A){         w = A.cols, h = A.rows, c = A.channels();         data = (u_char *) malloc(w * h * c * sizeof(u_char));         memcpy(data, A.data, w * h * c * sizeof(u_char));     }     cv::Mat to_cvMat(){         cv::Mat A(h, w, CV_8UC3, cv::Scalar(0, 0, 0));         memcpy(A.data, data, w * h * c * sizeof(u_char));         return A;     } }; double INTER_CUBIC_Fun(double x, double a = -0.5) {     x = abs(x);     if(0 <= x && x <= 1){         return 1 - (a + 3) * x * x + (a + 2) * x * x * x;     }     else if(1 < x && x <= 2){         return 8 * a * x - 5 * a * x * x + a * x * x * x - 4 * a;     }     else return 0; } int dimtovec(MyMat &a, int i, int j,int k) {     //return k * a.w * a.h + j * a.w + i;     return a.c * (a.w * j + i) + k; } /*  * A:数据矩阵 nw,nh:宽和长 interpolation_type:插值的方式  */ MyMat resize(MyMat A, int nw, int nh, std::string interpolation_type) {     MyMat B;     B.w = nw, B.h = nh, B.c = A.c;     B.data = (u_char *) malloc(sizeof(u_char) * B.w * B.h * B.c);     double dw = (double)A.w / nw;     double dh = (double)A.h / nh;     if(interpolation_type == "INTER_NEAREST"){ //最近邻插值         for(int i = 0; i < nw; i++){             for(int j = 0; j < nh; j++){                 int nx = i * dw;                 int ny = j * dh;                 //B.data[i * nh + j] = A.data[nx * A.h + ny];                 for(int k = 0; k < B.c; k++){                     int t1 = dimtovec(B, i, j, k), t2 = dimtovec(A, nx, ny, k);                     B.data[t1] = A.data[t2];                 }             }         }     }     else if(interpolation_type == "INTER_LINEAR"){ //双线性插值         for(int i = 0; i < nw; i++){             for(int j = 0; j < nh; j++){                 double nx = i * dw, ny = j * dh;                 if(nx >= A.w - 1)                     nx = A.w - 2;                 if(ny >= A.h - 1)                     ny = A.h - 2;                 int x1 = floor(nx), x2 = floor(nx + 1), y1 = floor(ny + 1), y2 = floor(ny);                 double alpha = (x2 - nx) / (x2 - x1), beta = (nx - x1) / (x2 - x1);                 for(int k = 0; k < A.c; k++){                     int Q11 = dimtovec(A, x1, y1 ,k);                     int Q12 = dimtovec(A, x1, y2, k);                     int Q21 = dimtovec(A, x2, y1, k);                     int Q22 = dimtovec(A, x2, y2, k);                     double R1 = alpha * A.data[Q11] + beta * A.data[Q21];                     double R2 = alpha * A.data[Q12] + beta * A.data[Q22];                     B.data[dimtovec(B, i, j, k)] = (y2 - ny) / (y2 -y1) * R1 + (ny - y1) / (y2 - y1) * R2;                 }             }         }     }     else if(interpolation_type == "INTER_CUBIC"){ //4x4像素点领域内的双立方插值         for(int i = 0; i < nw; i++){             for(int j = 0; j < nh; j++){                 int nx = i * dw, ny = j * dh;                 double dx = i * dw - nx, dy = j * dh - ny;                 for(int k = 0; k < B.c; k++){                     double sum = 0;                     for(int di = -1; di <= 2; di++){                         for(int dj = -1; dj <= 2; dj++){                             int x = nx + di, y = ny + dj;                             if(x < 0) x = 0;                             else if(x >= A.w){                                 x = A.w - 1;                             }                             if(y < 0 ) y = 0;                             else if(y >= A.h){                                 y = A.h - 1;                             }                             sum += A.data[dimtovec(A, x, y, k)] * INTER_CUBIC_Fun(di - dx) * INTER_CUBIC_Fun(dy - dj);                         }                     }                     if(sum > 255) sum = 255;                     if(sum < 0) sum = 0;                     B.data[dimtovec(B, i, j, k)] = sum;                 }             }         }     }     else if(interpolation_type == "INTER_LANCZOS4"){ //8x8像素领域内的Lanczos插值      } //    for(int i = 0; i < B.w * B.h; i++) std::cout << (int)B.data[i] << " "; //    std::cout << std::endl;     return B; } int main() {     //cv::Mat img(10, 10, CV_8UC3, cv::Scalar(255, 0, 0)); //    u_char *p = (u_char *)malloc(240 * 320 * sizeof(u_char)); //    memcpy(p, img.data, 5); //    for(int i = 0; i < 11; i++) std::cout << (int)p[i] << " ";     cv::Mat img = cv::imread("../test.jpg");    // cv::imshow("123", img);     //cv::waitKey(10);     //std::cout << img.channels() << std::endl;     MyMat A(img);      //for(int i = 0; i < A.w * A.h * A.c; i++) std::cout << (int)A.data[i] <<" ";       int x, y;     std::cin >> x >> y;     MyMat B = resize(A, x, y, "INTER_LINEAR");     cv::Mat C = B.to_cvMat(); //    cv::Mat out; //    cv::resize(img, out, cv::Size(500, 500) ,cv::INTER_NEAREST);     cv::imshow("123",C); //    cv::imwrite("../data.jpg", out);     cv::waitKey();      return 0; } 
文章来源: 图片插值
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!