图片任意角度旋转 梯形变换 任意四边形变换

来源:互联网 发布:云计算峰会的资金来源 编辑:程序博客网 时间:2024/05/20 07:16
#include <opencv.hpp>using namespace cv;typedef int s32;typedef long long s64;typedef s32 cfixed;typedef  unsigned char u8;#define cfixed_from_int(i)(((cfixed)(i)) << 16)#define cfixed_from_float(x)((cfixed)((x) * 65536.0f))#define cfixed_from_double(d)((cfixed)((d) * 65536.0))#define cfixed_to_int(f)((f) >> 16)#define cfixed_to_float(x)((float)((x) / 65536.0f))#define cfixed_const_1(cfixed_from_int(1))#define cfixed_const_e((cfixed)(1))#define cfixed_const_1_m_e(cfixed_const_1 - cfixed_const_e)#define cfixed_const_half(cfixed_const_1 >> 1)#define cfixed_frac(f)((f) & cfixed_const_1_m_e)#define cfixed_floor(f)((f) & (~cfixed_const_1_m_e))#define cfixed_ceil(f)(cfixed_floor((f) + 0xffff))#define cfixed_mul(x, y)((cfixed)((((s64)(x)) * (y)) >> 16))#define cfixed_div(x, y)((cfixed)((((s64)(x)) << 16) / (y)))#define cfixed_const_max((s64)0x7fffffff)#define cfixed_const_min(-((((s64)1) << 31)))//定点数辅助#define IPIXEL_EPSILON((cfixed)(2))#define IPIXEL_IS_SAME(a, b)(ipixel_within_epsilon(a, b, IPIXEL_EPSILON))#define IPIXEL_IS_ZERO(a)(ipixel_within_epsilon(a, 0, IPIXEL_EPSILON))#define IPIXEL_IS_ONE(a)(IPIXEL_IS_SAME(a, cfixed_const_1))#define IPIXEL_IS_INT(a)(IPIXEL_IS_ZERO(cfixed_frac(a)))#define IPIXEL_IS_UNIT(a)(IPIXEL_IS_SAME(a, cfixed_const_1) || \ IPIXEL_IS_SAME(a, -cfixed_const_1) || \ IPIXEL_IS_ZERO(a))enum {IPIXEL_FILTER_BILINEAR= 0,// 滤波模式:双线性过滤采样IPIXEL_FILTER_NEAREST= 1,// 滤波模式:最近采样};// 点的定义typedef struct {cfixed x;cfixed y;}ipixel_point_fixed_t;// 矢量定义typedef struct {cfixed vector[3];}ipixel_vector_t;// 矩阵定义typedef struct {cfixed matrix[3][3];}ipixel_transform_t;// 直线定义typedef struct {ipixel_point_fixed_t p1;ipixel_point_fixed_t p2;}ipixel_line_fixed_t;// 像素点定义typedef struct {u8 rgb[3];}ipixel_pixel_t;static inline s32 ipixel_within_epsilon(cfixed a, cfixed b, cfixed epsilon){cfixed c = a - b;if (c < 0) c = -c;return c <= epsilon;}// 线段与y轴相交的x坐标,ceil为是否向上去整static inline cfixed ipixel_line_fixed_x(const ipixel_line_fixed_t *l, cfixed y, s32 ceil){cfixed dx = l->p2.x - l->p1.x;s64 ex = ((s64)(y - l->p1.y)) * dx;cfixed dy = l->p2.y - l->p1.y;if (ceil) ex += (dy - 1);return l->p1.x + (cfixed)(ex / dy);}static inline s32 ipixel_line_span_bound(const ipixel_line_fixed_t *t, s32 y, s32 *x){cfixed x1, x2, y1, y2;s32 yt, yb;yt = cfixed_to_int(min(t->p1.y , t->p2.y));yb = cfixed_to_int(max(t->p1.y , t->p2.y));if (y < yt || y >= yb) return -2;y1 = cfixed_from_int(y);y2 = cfixed_from_int(y) + cfixed_const_1_m_e;x1 = cfixed_ceil(ipixel_line_fixed_x(t, y1, 0));x2 = cfixed_ceil(ipixel_line_fixed_x(t, y2, 0));*x = cfixed_to_int((x1 > x2)? x1 : x2);return 0;}static inline s32 ipixel_lines_bound(ipixel_line_fixed_t *t, int n ,s32 y, s32 *lx, s32 *rx){s32 xmin = 0x7fff, xmax = -0x7fff;s32 x[2];for (s32 i = 0 , j = 0; i < n;  i++) {if (ipixel_line_span_bound(&t[i], y, &x[j]) == 0) {j++;}}if (j == 2) {*lx = min(x[0],x[1]);*rx = max(x[0],x[1]);return 0;}return -1;}s32 ipixel_span_fetch(const Mat *img, s32 offset, s32 line, s32 width, u8 *card, const ipixel_transform_t *t);/* 绕任一点的旋转 变换矩阵(顺时针) * * 用下面的线性方程组来表示关系,求解方程组可以得到矩阵: * |Xdst|    |  cos  sin   (1-cos)*center.x - sin*center.y| |Xsrc| * |Ydst|    | -sin  cos   sin*center.x + (1-cos)*center.y| |Ysrc| * |  1 |    |   0    0                 1                 | |  1 | */s32 ibitmap_rotate2D(Mat *dst,Mat *src,float angle){angle *= 3.1415926f/180;    cfixed  alpha = cfixed_from_float(cos(angle));      cfixed  beta  = cfixed_from_float(sin(angle));ipixel_point_fixed_t center = {0};center.x = cfixed_from_float(src->cols/2.0);center.y = cfixed_from_float(src->rows/2.0);cfixed one_sub_alpha = cfixed_const_1 - alpha;s64 onesubalpha_mul_centerx = (s64)one_sub_alpha * center.x;s64 onesubalpha_mul_centery = (s64)one_sub_alpha * center.y;s64 beta_mul_centerx = (s64)beta * center.x;s64 beta_mul_centery = (s64)beta * center.y; ipixel_transform_t matrix = {0};matrix.matrix[0][0] =  alpha;matrix.matrix[0][1] =  beta;matrix.matrix[0][2] = (onesubalpha_mul_centerx - beta_mul_centery)>>16;matrix.matrix[1][0] =  -beta;matrix.matrix[1][1] =  alpha;matrix.matrix[1][2] = (onesubalpha_mul_centery + beta_mul_centerx)>>16;matrix.matrix[2][0] =  0;matrix.matrix[2][1] =  0;matrix.matrix[2][2] =  cfixed_const_1;ipixel_point_fixed_t srcQuad[4] = {0};ipixel_point_fixed_t dstQuad[4] = {0};srcQuad[0].x = 0;srcQuad[0].y = 0; srcQuad[1].x = 0;srcQuad[1].y = cfixed_from_int(src->rows);srcQuad[2].x = cfixed_from_int(src->cols);srcQuad[2].y = cfixed_from_int(src->rows);srcQuad[3].x = cfixed_from_int(src->cols);srcQuad[3].y = 0;cfixed minX = 0x7fffffff;cfixed maxX = 0x80000000;cfixed minY = 0x7fffffff;cfixed maxY = 0x80000000;cfixed offsetx = cfixed_from_float((dst->cols - src->cols)/2.0);cfixed offsety = cfixed_from_float((dst->rows - src->rows)/2.0);for (s32 i = 0; i < 4; i++) {dstQuad[i].x = (cfixed)(((s64)srcQuad[i].x * (s64)matrix.matrix[0][0] + (s64)srcQuad[i].y * (s64)matrix.matrix[0][1])>>16) + matrix.matrix[0][2] + offsetx;dstQuad[i].y = (cfixed)(((s64)srcQuad[i].x * (s64)matrix.matrix[1][0] + (s64)srcQuad[i].y * (s64)matrix.matrix[1][1])>>16) + matrix.matrix[1][2] + offsety;if(dstQuad[i].x < minX) minX = dstQuad[i].x;if(dstQuad[i].x > maxX) maxX = dstQuad[i].x;if(dstQuad[i].y < minY) minY = dstQuad[i].y;if(dstQuad[i].y > maxY) maxY = dstQuad[i].y;}matrix.matrix[0][0] =  alpha;matrix.matrix[0][1] =  - beta;matrix.matrix[0][2] =  (onesubalpha_mul_centerx + beta_mul_centery - (s64)alpha*offsetx + (s64)beta*offsety)>>16;matrix.matrix[1][0] =  beta;matrix.matrix[1][1] =  alpha;matrix.matrix[1][2] =  (onesubalpha_mul_centery - beta_mul_centerx - (s64)alpha*offsety - (s64)beta*offsetx)>>16;matrix.matrix[2][0] =  0;matrix.matrix[2][1] =  0;matrix.matrix[2][2] =  cfixed_const_1;//四根直线ipixel_line_fixed_t lines[4] = {0};for (s32 i = 0 ; i < 4 ;i++){lines[i].p1 = dstQuad[i];lines[i].p2 = dstQuad[(i+1)%4];}//生成扫描区域s32 width  = cfixed_to_int(maxX - minX);s32 height = cfixed_to_int(maxY - minY);s32 starty = cfixed_to_int(minY);s32 endx   = cfixed_to_int(maxX); size_t BuffSize = dst->step;u8 *card = (u8*)malloc(BuffSize);  //工作空间申请// 主要绘制循环for (s32 j = 0; j < height; j++) {s32 xl, xr, xw;s32 line = j + starty;// 取得该扫描的X轴左右对应坐标if (ipixel_lines_bound(&lines[0],4,line, &xl, &xr) != 0) continue;if (xl < 0) xl = 0; if (xr >= endx) xr = endx - 1;xw = xr - xl;memset(card,0,BuffSize);ipixel_span_fetch(src, xl, line, xw, card, &matrix);memcpy(dst->data + dst->step*line  + xl*dst->elemSize(), card, xw*dst->elemSize());}free(card);return 0;}#define IMATRIX_SOLVE_WORKMEM(n, m) ((sizeof(s32) * n + sizeof(float) * (m * n + n * n)))// solve X from AX=B, result is saved to X// A(0-(n-1), 0-(n-1)), X(0-(n-1), 0-(m-1)), B(0-(n-1), 0-(m-1))// A(i, j) = A[i * n + j], B(i, j) = B[i * m + j]// returns zero for success, others for error.s32 imatrix_solve_n_m(const float A[], const float B[], float X[], s32 n, s32 m){// 求解矩阵所需要的临时内存大小u8 *workmem = (u8*)malloc(IMATRIX_SOLVE_WORKMEM(n, m));s32 *js, l, k, i, j, is, p, q;float *a, *b, d, t;// initialize a = (float*)(workmem + sizeof(s32) * n);b = (float*)(workmem + sizeof(s32) * n + sizeof(float) * n * n);for (i = n * n - 1; i >= 0; i--) a[i] = A[i];for (i = m * n - 1; i >= 0; i--) b[i] = B[i];js = (s32*)workmem;is = 0;l = 1;// solve main loopfor (k = 0; k <= n - 1; k++) { d = 0.0;for (i = k; i <= n - 1; i++) {for (j = k; j <= n - 1; j++){ t = a[i * n + j];if (t < 0) t = -t;if (t > d) { d = t; js[k] = j; is = i; }}}if (d + 1.0 == 1.0) l = 0;else{ if (js[k] != k) {for (i = 0; i <= n - 1; i++) { p = i * n + k; q = i * n + js[k];t = a[p]; a[p] = a[q]; a[q] = t;}}if (is != k) { for (j = k; j <= n - 1; j++) { p = k * n + j; q = is * n + j;t = a[p]; a[p] = a[q]; a[q] = t;}for (j = 0; j <= m - 1; j++) { p = k * m + j; q = is * m + j;t = b[p]; b[p] = b[q]; b[q] = t;}}}// check if no resultif (l == 0){return -1;}d = a[k * n + k];for (j = k + 1; j <= n - 1; j++) { p = k * n + j; a[p] = a[p] / d;}for (j = 0; j <= m - 1; j++) {p = k * m + j; b[p] = b[p] / d;}for (j = k + 1; j <= n - 1; j++) {for (i = 0; i <= n - 1; i++) { p = i * n + j;if (i != k) {a[p] = a[p] - a[i * n + k] * a[k * n + j];}}}for (j = 0; j <= m-1; j++) {for (i = 0; i <= n - 1; i++) { p = i * m + j;if (i != k) {b[p] = b[p] - a[i * n + k] * b[k * m + j];}}}}for (k = n - 1; k >= 0; k--){if (js[k] != k) {for (j = 0; j <= m - 1; j++) { p = k * m + j; q = js[k] * m + j;t = b[p]; b[p] = b[q]; b[q] = t;}}}for (i = m * n - 1; i >= 0; i--) X[i] = b[i];free(workmem);return 0;}/* 计算透视投影的变换矩阵 *      c00*xi + c01*yi + c02 * ui = --------------------- *      c20*xi + c21*yi + c22 * *      c10*xi + c11*yi + c12 * vi = --------------------- *      c20*xi + c21*yi + c22 * * 用下面的线性方程组来表示关系,求解方程组可以得到矩阵: * / x0 y0  1  0  0  0 -x0*u0 -y0*u0 \ /c00\ /u0\ * | x1 y1  1  0  0  0 -x1*u1 -y1*u1 | |c01| |u1| * | x2 y2  1  0  0  0 -x2*u2 -y2*u2 | |c02| |u2| * | x3 y3  1  0  0  0 -x3*u3 -y3*u3 |.|c10|=|u3|, * |  0  0  0 x0 y0  1 -x0*v0 -y0*v0 | |c11| |v0| * |  0  0  0 x1 y1  1 -x1*v1 -y1*v1 | |c12| |v1| * |  0  0  0 x2 y2  1 -x2*v2 -y2*v2 | |c20| |v2| * \  0  0  0 x3 y3  1 -x3*v3 -y3*v3 / \c21/ \v3/ * * 其中: *   cij - 变换剧照的元素, c22 = 1 */s32 itransform_perspective(float m[], const float src[], const float dst[]){float a[8][8], b[8], x[8];s32 i;    for (i = 0; i < 4; i++){        a[i][0] = a[i + 4][3] = src[i * 2 + 0];        a[i][1] = a[i + 4][4] = src[i * 2 + 1];        a[i][2] = a[i + 4][5] = 1;        a[i][3] = a[i][4] = a[i][5] = 0;        a[i + 4][0] = a[i + 4][1] = a[i + 4][2] = 0;        a[i][6] = -src[i * 2 + 0] * dst[i * 2 + 0];        a[i][7] = -src[i * 2 + 1] * dst[i * 2 + 0];        a[i + 4][6] = -src[i * 2 + 0] * dst[i * 2 + 1];        a[i + 4][7] = -src[i * 2 + 1] * dst[i * 2 + 1];        b[i] = dst[i * 2 + 0];        b[i + 4] = dst[i * 2 + 1];    }if (imatrix_solve_n_m(&a[0][0], b, x, 8, 1) != 0)return -1;for (i = 0; i < 8; i++) m[i] = x[i];m[8] = 1.0;return 0;}// 初始化透视矩阵s32 ipixel_transform_init_perspective(ipixel_transform_t *matrix,  const  ipixel_point_fixed_t *src,  const  ipixel_point_fixed_t *dst){float fsrc[8];float fdst[8];float fmat[9];s32 i, j;s64 n;for (i = 0; i < 4; i++){fsrc[i * 2 + 0] = cfixed_to_float(src[i].x);fsrc[i * 2 + 1] = cfixed_to_float(src[i].y);fdst[i * 2 + 0] = cfixed_to_float(dst[i].x);fdst[i * 2 + 1] = cfixed_to_float(dst[i].y);}if (itransform_perspective(fmat, fsrc, fdst) != 0)return -1;for (i = 0; i < 3; i++) {for (j = 0; j < 3; j++) {n = ((s64)( fmat[i * 3 + j] * 65536.0));  //注意if (n < cfixed_const_min || n > cfixed_const_max){return -2;}matrix->matrix[i][j] = (cfixed)n;}}return 0;}s32 ibitmap_quadtransform(Mat *dst,Mat *src,ipixel_point_fixed_t* p ){//四根直线ipixel_line_fixed_t lines[4] = {0};for (s32 i = 0 ; i < 4 ;i++){lines[i].p1 = p[i];lines[i].p2 = p[(i+1)%4];}cfixed minX = 0x7fffffff;cfixed maxX = 0x80000000;cfixed minY = 0x7fffffff;cfixed maxY = 0x80000000;for (s32 i = 0; i < 4; i++) {if(p[i].x < minX) minX = p[i].x;if(p[i].x > maxX) maxX = p[i].x;if(p[i].y < minY) minY = p[i].y;if(p[i].y > maxY) maxY = p[i].y;}//生成扫描区域s32 width  = cfixed_to_int(maxX - minX);s32 height = cfixed_to_int(maxY - minY);s32 starty = cfixed_to_int(minY);s32 endx   = cfixed_to_int(maxX); size_t BuffSize = dst->step;u8 *card = (u8*)malloc(BuffSize);  //工作空间申请ipixel_point_fixed_t srcQuad[4];srcQuad[0].x = 0;srcQuad[0].y = 0;srcQuad[1].x = 0;srcQuad[1].y = cfixed_from_int(src->rows);srcQuad[2].x = cfixed_from_int(src->cols);srcQuad[2].y = cfixed_from_int(src->rows);srcQuad[3].x = cfixed_from_int(src->cols);srcQuad[3].y = 0;//计算变换矩阵ipixel_transform_t matrix = {0};if (ipixel_transform_init_perspective(&matrix, p,&srcQuad[0]) != 0) return -8;// 主要绘制循环for (s32 j = 0; j < height; j++) {s32 xl, xr, xw;s32 line = j + starty;// 取得该扫描的X轴左右对应坐标if (ipixel_lines_bound(&lines[0],4,line, &xl, &xr) != 0) continue;if (xl < 0) xl = 0; if (xr >= endx) xr = endx - 1;xw = xr - xl;memset(card,0,BuffSize);ipixel_span_fetch(src, xl, line, xw, card, &matrix);memcpy(dst->data + dst->step*line  + xl*dst->elemSize(), card, xw*dst->elemSize());}free(card);return 0;}// 矩阵同点相乘: matrix * vectors32 ipixel_transform_point(const ipixel_transform_t *t,ipixel_vector_t *vector){ipixel_vector_t result = {0};s64 partial;s64 v;s32 i, j;for (j = 0; j < 3; j++) {v = 0;for (i = 0; i < 3; i++) {partial = ((s64)t->matrix[j][i])*((s64)vector->vector[i]);v += partial >> 16 ;}if (v > cfixed_const_max || v < cfixed_const_min)return -1;result.vector[j] = (cfixed)v;}*vector = result;if (vector->vector[2] == 0) return -2;return 0;}void ibitmap_fetch_pixel(const Mat* img , ipixel_pixel_t* pr ,cfixed x, cfixed y){s32 x0 = (x < 0)? 0 : (x >= img->cols)? (img->cols - 1) : x;s32 y0 = (y < 0)? 0 : (y >= img->rows)? (img->rows - 1) : y;u8* pdata = img->data + y0*img->step + x0 * img->elemSize();pr->rgb[0] = pdata[0];pr->rgb[1] = pdata[1];pr->rgb[2] = pdata[2];}void ibitmap_fetch_pixel_bilinear(const Mat* img , ipixel_pixel_t* pr ,cfixed x, cfixed y){cfixed x1 = x - cfixed_const_1 / 2; cfixed y1 = y - cfixed_const_1 / 2; cfixed distx = (x1 >> 8) & 0xff;cfixed disty = (y1 >> 8) & 0xff;x1 = cfixed_to_int(x1); y1 = cfixed_to_int(y1); s32 x2 = x1 + 1; s32 y2 = y1 + 1; ipixel_pixel_t c[2][2] = {0};ibitmap_fetch_pixel(img ,&c[0][0],x1 ,y1 );ibitmap_fetch_pixel(img ,&c[0][1],x2 ,y1 );ibitmap_fetch_pixel(img ,&c[1][0],x1 ,y2 );ibitmap_fetch_pixel(img ,&c[1][1],x2 ,y2 );s32 distxy = distx * disty;s32 distxiy = (distx << 8) - distxy;/* distx * (256 - disty) */s32 distixy = (disty << 8) - distxy;/* disty * (256 - distx) */s32 distixiy = 256 * 256 - (disty << 8) - (distx << 8) + distxy;/* (256 - distx) * (256 - disty) */for(s32 i = 0 ; i < 3 ; i++){pr->rgb[i] = cfixed_to_int(c[0][0].rgb[i] * distixiy + c[0][1].rgb[i] * distxiy +c[1][0].rgb[i] * distixy + c[1][1].rgb[i] * distxy);}}s32 ipixel_span_fetch(const Mat *img, s32 offset, s32 line, s32 width, u8 *card, const ipixel_transform_t *t ){ipixel_vector_t vec, step;vec.vector[0] = cfixed_from_int(offset) + cfixed_const_half;vec.vector[1] = cfixed_from_int(line) + cfixed_const_half;vec.vector[2] = cfixed_const_1;if (t != NULL){if (ipixel_transform_point(t, &vec) != 0) return -12;step.vector[0] = t->matrix[0][0];step.vector[1] = t->matrix[1][0];step.vector[2] = t->matrix[2][0];}else {step.vector[0] = cfixed_const_1;step.vector[1] = 0;step.vector[2] = 0;}if (IPIXEL_IS_ZERO(step.vector[2])) {step.vector[2] = 0;if (IPIXEL_IS_ONE(vec.vector[2])) vec.vector[2] = cfixed_const_1;if (vec.vector[2] != cfixed_const_1) {cfixed w = vec.vector[2];vec.vector[0] = cfixed_div(vec.vector[0], w);vec.vector[1] = cfixed_div(vec.vector[1], w);vec.vector[2] = cfixed_const_1;step.vector[0] = cfixed_div(step.vector[0], w);step.vector[1] = cfixed_div(step.vector[1], w);step.vector[2] = cfixed_div(step.vector[2], w);}}cfixed u, v, w, du, dv, dw, x, y; u = vec.vector[0]; v = vec.vector[1]; w = vec.vector[2]; du = step.vector[0]; dv = step.vector[1]; dw = step.vector[2]; u8* pdata = NULL;ipixel_pixel_t pixel = {0};s32 filter = IPIXEL_FILTER_BILINEAR;  //IPIXEL_FILTER_NEARESTif (filter == IPIXEL_FILTER_BILINEAR){ if (w == cfixed_const_1 && dw == 0) { for (; width > 0; width--) { ibitmap_fetch_pixel_bilinear(img , &pixel ,u, v);memcpy(card , &pixel , img->elemSize());card += img->elemSize(); u += du;v += dv;  w += dw;} }else { for (; width > 0;  width--){ if (w != 0) { x = cfixed_div(u, w); y = cfixed_div(v, w); }else {  x = 0, y = 0; } ibitmap_fetch_pixel_bilinear(img , &pixel ,x, y );memcpy(card , &pixel , img->elemSize());card += img->elemSize(); u += du;v += dv; w += dw;} } }else//IPIXEL_FILTER_NEAREST{if (w == cfixed_const_1 && dw == 0) { for (; width > 0; width--) { ibitmap_fetch_pixel(img , &pixel ,u, v );memcpy(card , &pixel , img->elemSize());card += img->elemSize(); u += du;v += dv; w += dw;} }else { for (; width > 0;  width--){ if (w != 0) { x = cfixed_div(u, w); y = cfixed_div(v, w); }else {  x = 0, y = 0; } s32 x0 = cfixed_to_int(x - cfixed_const_e); s32 y0 = cfixed_to_int(y - cfixed_const_e); ibitmap_fetch_pixel(img,&pixel,x0,y0);memcpy(card , &pixel , 3);card += img->elemSize(); u += du;v += dv; w += dw;} } }return 0;}typedef struct {s32 bottom;s32 top;s32 bottom_startx;s32 bottom_endx;s32 top_startx;s32 top_endx;}VTrapeParam_t;void inline ibitmap_Linearfill(u8* dst , u8* src , cfixed s , cfixed d){if (s > d){cfixed step_x = cfixed_div(s,d);s32 d_int = cfixed_to_int(d);cfixed fixed_src = 0;for (s32 i = 0; i < d_int ; i++){memcpy(dst , src + 3*cfixed_to_int(fixed_src) , 3 );fixed_src += step_x;dst += 3;}} else{cfixed step_x = cfixed_div(d,s);s32 s_int = cfixed_to_int(s);s32 size = 3*cfixed_to_int(cfixed_ceil(step_x));cfixed fixed_dst = 0;for (s32 i = 0; i < s_int ; i++){memcpy(dst +  3 * cfixed_to_int(fixed_dst), src  , size);fixed_dst += step_x;src += 3;}}}void ibitmap_HTrapetransform( Mat *dst,Mat *src,VTrapeParam_t *thiz){s32 bottom         = thiz->bottom;s32 top   = thiz->top;s32 bottom_startx  = thiz->bottom_startx;s32 bottom_endx    = thiz->bottom_endx;s32 top_startx     = thiz->top_startx;s32 top_endx       = thiz->top_endx;u8* pSrcData = src->data;u8* pDstData = dst->data;u8* pSrc = src->data;u8* pDst = dst->data;cfixed starty_dst = cfixed_from_int(top);cfixed starty_src = cfixed_from_int(0);cfixed endy_dst   = cfixed_from_int(bottom);cfixed endy_src   = cfixed_from_int(src->rows);cfixed y_dst      = starty_dst;cfixed y_src      = starty_src;cfixed startx_dst = cfixed_from_int(top_startx) ;cfixed endx_dst   = cfixed_from_int(top_endx) ;cfixed endx_src   = cfixed_from_int(src->cols);cfixed src_dy     = cfixed_div(endy_src - starty_src,endy_dst - starty_dst);cfixed dst_dx1    = cfixed_div(cfixed_from_int(bottom_startx - top_startx),cfixed_from_int(bottom - top));cfixed dst_dx2    = cfixed_div(cfixed_from_int(bottom_endx - top_endx),cfixed_from_int(bottom - top));while(y_dst < endy_dst && y_src < endy_src){cfixed x_dst = startx_dst;cfixed x_src = 0;cfixed dx_src =  cfixed_div(endx_src ,endx_dst - startx_dst);pDst = pDstData + cfixed_to_int(y_dst)*dst->step + cfixed_to_int(startx_dst)*3;pSrc = pSrcData + cfixed_to_int(y_src)*src->step ;ibitmap_Linearfill(pDst , pSrc  , endx_src , endx_dst - startx_dst);  startx_dst += dst_dx1;endx_dst   += dst_dx2;y_dst += cfixed_const_1;y_src += src_dy ;}}s32 main(){Mat src = imread("res_fish.bmp");imshow("Src" , src);//水平梯形变换Mat HTrapedst = Mat::zeros(600,800, CV_8UC3);    //创建目标图像VTrapeParam_t tParam = {0};tParam.bottom = 500;tParam.top = 100;tParam.top_startx = 200;tParam.top_endx = 350;tParam.bottom_startx = 10;tParam.bottom_endx = 600;ibitmap_HTrapetransform(&HTrapedst , &src , &tParam);imshow("HTrapedst" , HTrapedst);//任意四边形变换Mat Quaddst = Mat::zeros(600,800, CV_8UC3);    //创建目标图像ipixel_point_fixed_t dstQuad[4] = {0};dstQuad[0].x = cfixed_from_int(10);  dstQuad[0].y = cfixed_from_int(70);  dstQuad[1].x = cfixed_from_int(200); dstQuad[1].y = cfixed_from_int(230); dstQuad[2].x = cfixed_from_int(250); dstQuad[2].y = cfixed_from_int(100); dstQuad[3].x = cfixed_from_int(130); dstQuad[3].y = cfixed_from_int(20);  ibitmap_quadtransform(&Quaddst, &src,&dstQuad[0]);imshow("Quaddst" , Quaddst);s32 dst_Side_length = sqrt((float)src.cols*src.cols+(float)src.rows*src.rows)+1;s32 angle = 0;while (1){++angle %= 360;Mat Rotatedst = Mat::zeros(dst_Side_length,dst_Side_length, CV_8UC3);    //创建目标图像ibitmap_rotate2D(&Rotatedst,&src,angle);imshow("Dstimage", Rotatedst);waitKey(40);}}

	
				
		
原创粉丝点击