精华内容
下载资源
问答
  • 有时候图像中拍的海报,视频,文件等因为拍摄角度问题,结果在图像中显示为任意四边形。该程序提供了一种将这个任意四边形转换为矩形的方法
  • #include using namespace cv; typedef int s32; typedef long long s64; typedef s32 cfixed; typedef unsigned char u8;...#define cfixed_from_int(i) (((cfixed)(i)) ) #define cfixed_from_float(x) ((c
    #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 loop
    	for (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 result
    		if (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 * vector
    s32 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_NEAREST
    	if (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);
    	}
    }
    

    展开全文
  • 接触C有一段时间了,看多好次输出各种图形的练习题,自己也曾经编写过,今天...3、键盘任意输入,只有符合要求的输入(0~4)被执行,其他均为非法输入,返回程序,重新选择 4、屏蔽输入结束时的“回车”,用函数...

    接触C有一段时间了,看多好次输出各种图形的练习题,自己也曾经编写过,今天整理在一起,为了给自己留下记录,也为了跟同样在学习路上的朋友们一起交流;

    代码采用主函数、分函数结构

    实现以下功能

    1、选择性输出 想要的图形 以及 图形大小

    2、循环功能,主动选择退出

    3、键盘任意输入,只有符合要求的输入(0~4)被执行,其他均为非法输入,返回程序,重新选择

    4、屏蔽输入结束时的“回车”,用函数 fflush(stdin);   这个函数的作用是清除缓存,为下一次输入做准备

    部分截图:

    以下是代码:供参考

    /*输出图形小程序*/
    #include "stdio.h"
    #include "stdlib.h"
    //声明函数,三角形、矩形、平行四边形、菱形 
    int sanj();
    int juxi();
    int pinx();
    int ling();
    void main()
    {
    	int a;
    	printf("*******输出图形小程序*******\n\n\t【1】三角形\n\t【2】矩形\n\t【3】平行四边形\n\t【4】菱形\n\t【0】退出\n\n");
    	printf("请选择要执行代号: ");
    	//scanf("%d",&a); 			//这种取值方法只能取数值 
    	a=getchar();				//键盘获取任意字符 
    	printf("\n\n");
    	a=a-'0';				   //将字符转换为ASCII码 ,并与 ’0‘ 比较大小 
    	if(!(a>=0&&a<=4))  a=5;    //对于比值不是 0-4 之间的的数统一赋值为 5 (不是0~4的都可以) 
    	switch(a)				   //进入对应的函数	
    	{
    		case 1: sanj();break;
    		case 2: juxi();break;
    		case 3: pinx();break;
    		case 4: ling();break;
    		case 0: exit(0);
    		default: printf("选择错误,返回主程序\n\n");
    				 fflush(stdin);		//这个函数的作用是清除缓存,返回主函数之前使用, 为下一次取值做准备
    				 main();			//返回主函数 
    	}
    }
    
    int sanj()			//输出三角形 函数 
    {	int s1,s2,s3,s;
    	printf("【1】三角形  行数:  ");
    	scanf("%d",&s);
    	printf("\n\n ");
    	s3=s*2-1;
    	printf("\n");
    	for(s1=1;s1<=s;s1++)
    	{	printf("\t");
    		for(s2=1;s2<=s-s1;s2++)printf("  ");
    		for(s3=1;s3<=s1*2-1;s3++)printf("* ");
    		printf("\n");
    	}
    	printf("\n\n");
    	fflush(stdin);		//这个函数的作用是清除缓存,返回主函数之前使用, 为下一次取值做准备
    	main();			//返回主函数 ;
    }
    
    int juxi()		//输出矩形 函数 
    {	int s1,s2,s;
    	printf("【2】矩形 行数:  ");
    	scanf("%d",&s);
    	printf("\n\n");
    	for(s1=1;s1<=s;s1++)
    	{	printf("\t");
    		for(s2=1;s2<=s;s2++)printf("* ");
    			printf("\n");
    	}
    	printf("\n\n");
    	fflush(stdin);		//这个函数的作用是清除缓存,返回主函数之前使用, 为下一次取值做准备
    	main();			//返回主函数 
    }
    
    int pinx()		//输出平行四边形 函数 
    {	int s1,s2,s3,s;
    	printf("【3】平行四边形 行数:  ");
    	scanf("%d",&s);
    	printf("\n\n");
    	for(s3=1;s3<=s;s3++)
    	{
    		printf("\t");
    		for(s1=1;s1<=s-s3;s1++)printf(" ");
    			for(s2=1;s2<=s;s2++)printf("* ");
    				printf("\n");
    	}
    	printf("\n\n");
    	fflush(stdin);		//这个函数的作用是清除缓存,返回主函数之前使用, 为下一次取值做准备
    	main();			//返回主函数 
    }
    int ling()		//输出菱形 函数 
    {	int s1,s2,s3,s4,s5,s,row;
    	printf("【4】菱形 行数:  ");
    	scanf("%d",&s);
    	printf("\n\n");
    	row=s/2;
    	if(s%2==0)		//输出行数为 偶数 
    	{
    		for(s1=1;s1<=s;s1++)
    		{
    			if(s1<=row)
    	        {printf("\t");
    			for(s2=1;s2<=row-s1;s2++)printf("  ");
    				for(s3=1;s3<=s1*2-1;s3++)printf("* ");
    					printf("\n");
    			}
    	        else
    			{
    				printf("\t");
    				for(s4=1;s4<=s1-row-1;s4++)printf("  ");
    					for(s5=1;s5<=(s-s1)*2+1;s5++)printf("* ");
    						printf("\n");
    			}
    	}
    	}
    	else		//输出行数为 奇数 
    	{   row++;
    		for(s1=1;s1<=s;s1++)
    		{
    			if(s1<=row)
    	        {printf("\t");
    			for(s2=1;s2<=row-s1;s2++)printf("  ");
    				for(s3=1;s3<=s1*2-1;s3++)printf("* ");
    					printf("\n");
    			}
    	        else
    			{
    				printf("\t");
    				for(s4=1;s4<=s1-row;s4++)printf("  ");
    					for(s5=1;s5<=(s-s1)*2+1;s5++)printf("* ");
    						printf("\n");
    			}
    		}
    	}
    	printf("\n\n");
    	fflush(stdin);		//这个函数的作用是清除缓存,返回主函数之前使用, 为下一次取值做准备
    	main();			//返回主函数 
    }

     

     

     

     

    展开全文
  • 计算在 4 个顶点或 x、y、宽度、高度(或两者)中指定的两个任意四边形的相交面积。
  • visio画任意形状图形

    千次阅读 2017-06-16 21:19:00
    1,连接线--右击---曲线连接线 2,选中组合 3,开发工具--操作--连接--填充 转载于:https://www.cnblogs.com/dalanjing/p/7029293.html

    1,连接线--右击---曲线连接线

    2,选中组合

    3,开发工具--操作--连接--填充

    转载于:https://www.cnblogs.com/dalanjing/p/7029293.html

    展开全文
  • 写在前面:之前是先得到任意四边形的最小外接矩形,再使用opencv进行裁剪,但是这样会引入噪声。所以在此记录下,如何直接裁剪原任意四边形区域。 思路: 1.计算要裁剪区域四边形的相对水平方向的旋转角度; 2.将...

    写在前面:之前是先得到任意四边形的最小外接矩形,再使用opencv进行裁剪,但是这样会引入噪声。所以在此记录下,如何直接裁剪原任意四边形区域。

    思路:

    1.计算要裁剪区域四边形的相对水平方向的旋转角度;

    2.将原图旋转该角度,以使得要裁剪的区域旋转到水平方向;

    3.将要裁剪区域的坐标做相应的转换,转换为旋转后的坐标;

    4.对该区域进行裁剪。

    # -*- coding:utf-8 -*-
    import cv2
    from math import *
    import numpy as np
    import time,math
    import os
    import re
    
    '''旋转图像并剪裁'''
    def rotate(
            img,  # 图片
            pt1, pt2, pt3, pt4,
            newImagePath
    ):
        print pt1,pt2,pt3,pt4
        withRect = math.sqrt((pt4[0] - pt1[0]) ** 2 + (pt4[1] - pt1[1]) ** 2)  # 矩形框的宽度
        heightRect = math.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) **2)
        print withRect,heightRect
        angle = acos((pt4[0] - pt1[0]) / withRect) * (180 / math.pi)  # 矩形框旋转角度
        print angle
    
        if pt4[1] > pt1[1]:
            print "顺时针旋转"
        else:
            print "逆时针旋转"
            angle = -angle
    
        height = img.shape[0]  # 原始图像高度
        width = img.shape[1]   # 原始图像宽度
        rotateMat = cv2.getRotationMatrix2D((width / 2, height / 2), angle, 1)  # 按angle角度旋转图像
        heightNew = int(width * fabs(sin(radians(angle))) + height * fabs(cos(radians(angle))))
        widthNew = int(height * fabs(sin(radians(angle))) + width * fabs(cos(radians(angle))))
    
        rotateMat[0, 2] += (widthNew - width) / 2
        rotateMat[1, 2] += (heightNew - height) / 2
        imgRotation = cv2.warpAffine(img, rotateMat, (widthNew, heightNew), borderValue=(255, 255, 255))
    
        # 旋转后图像的四点坐标
        [[pt1[0]], [pt1[1]]] = np.dot(rotateMat, np.array([[pt1[0]], [pt1[1]], [1]]))
        [[pt3[0]], [pt3[1]]] = np.dot(rotateMat, np.array([[pt3[0]], [pt3[1]], [1]]))
        [[pt2[0]], [pt2[1]]] = np.dot(rotateMat, np.array([[pt2[0]], [pt2[1]], [1]]))
        [[pt4[0]], [pt4[1]]] = np.dot(rotateMat, np.array([[pt4[0]], [pt4[1]], [1]]))
    
        # 处理反转的情况
        if pt2[1] > pt4[1]:
            pt2[1],pt4[1] = pt4[1],pt2[1]
        if pt1[0] > pt3[0]:
            pt1[0],pt3[0] = pt3[0],pt1[0]
    
        imgOut = imgRotation[int(pt2[1]):int(pt4[1]), int(pt1[0]):int(pt3[0])]
        cv2.imwrite(newImagePath, imgOut)  # 裁减得到的旋转矩形框
        return imgRotation  # rotated image
    
    
    # 根据四点画原矩形
    def drawRect(img,pt1,pt2,pt3,pt4,color,lineWidth):
        cv2.line(img, pt1, pt2, color, lineWidth)
        cv2.line(img, pt2, pt3, color, lineWidth)
        cv2.line(img, pt3, pt4, color, lineWidth)
        cv2.line(img, pt1, pt4, color, lineWidth)
    
    # 读出文件中的坐标值
    def ReadTxt(directory,imageName,last):
        fileTxt = last  # txt文件名
        getTxt = open(fileTxt, 'r')  # 打开txt文件
        lines = getTxt.readlines()
        length = len(lines)
        for i in range(0,length):
            items = lines[i].split(',')
    
            pt1 = [int(items[0]), int(items[1])]
            pt4 = [int(items[2]), int(items[3])]
            pt3 = [int(items[4]), int(items[5])]
            pt2 = [int(items[6]), int(items[7])]
    
            imgSrc = cv2.imread(imageName)
            rotate(imgSrc,pt1,pt2,pt3,pt4,str(i)+'_'+imageName)
    
    
    if __name__=="__main__":
        directory = "."
        last = 'image_1210.txt'
        imageName = "image_1210.jpg"
        ReadTxt(directory,imageName,last)

     

    展开全文
  • visio给任意图形进行填充

    千次阅读 2019-05-16 09:55:00
    使用visio给图形填充颜色的条件:图形必须是封闭的!!! 但是很多人不明白:我明明画的图形是封闭...首先随意画一个四边形 这时是无法进行颜色填充的。 首先选择文件--选项--高级,勾选以开发人员模式运行 ...
  • 平行四边形 概述 平行四边形是初二最难的一章,对中考的影响较大 目前仍有考试做不出来的风险(不小),仍需提高绝对水平 概念 图形的旋转 旋转后的图形与原图形全等 对应点与旋转...
  • 自定义view,使用Canvas制作一个可拖动改变任意形状的四边形,并填充颜色。。
  • 在C#用GDI+实现图形图像的任意变形效果?

    万次阅读 热门讨论 2004-12-04 17:59:00
    如何实现类似PHOTOSHOP中的图像任意变形效果,目前GDI+可以轻松实现由长方形变成任意平行四边形,但无法轻意解决变成梯形、三角形和任意四边形。例如下例:扭曲变形效果之一:扭曲变形效果之二:在下一代操作系统Vista...
  • 本文转载自:  ...如何实现类似PHOTOSHOP中的图像任意变形效果,目前GDI+可以轻松实现由长方形变成任意平行四边形,但无法轻意解决变成梯形、三角形和任意四边形。 例如下例: 扭曲变形效果之一: 扭曲变
  • 平面图形任意变形问题的解决方案

    千次阅读 2005-10-10 10:05:00
    http://61.186.252.131/expert/topic/886/886049.xml?temp=.9779779可惜没有写出源代码,但我相信此解决...MSN(Email): a3news#hotmail.com相关问题:在C#用GDI+实现图形图像的任意变形效果? ---------------------
  • //根据路径画出图形 } 判断是否点中四个点的坐标范围: private boolean isRangeOfView(float dx,float dy,float ev_x,float ev_y) { //dx:点的x轴 dy:点的y轴 ev_x:手势触摸到的x轴 ev_y:手势触摸到的y轴 // ...
  • 如何实现类似PHOTOSHOP中的图像任意变形效果,目前GDI+可以轻松实现由长方形变成任意平行四边形,但无法轻意解决变成梯形、三角形和任意四边形。例如下例:扭曲变形效果之一:扭曲变形效果之二:在下一代操作系统Vista...
  • 判断四边形

    2021-10-15 11:35:17
    给出平面上a,b,c,d四个点的坐标,依次连接a-b,b-c,c-d,d-a,请你写程序判断得到的图形是否是凸四边形. 关于输入 输入包含多组数据,每组数据一行,包含8个整数(绝对值都不大于1000),依次为a,b,c,d四个点的坐标. 关于输出...
  • 在C 用GDI+实现图形图像的任意变形效果
  • 一、绘制 GL_QUADS 四边形、 二、绘制多个四边形、 三、相关资源
  • k++) {//平行四边形的宽可自定义为任意值,这里定义为3*row System.out.print("*"); } System.out.println(); } } public static void showHollowDiamond(int row) { int i,j,k; for(i=1; i;...
  • 平行四边形

    2011-06-02 07:21:00
    从等腰三角形底边上任意一点分别作两腰的平行线,那么所得的平行四边形的周长等于这个等腰三角形的( ) A.周长 B.周长的一半 C.腰长 D.腰长的2倍 平行四边形不具有的性质是( ) A.对边平行 B.对边相等 C.对...
  • 不规则四边形的平行四边形

    千次阅读 2013-11-21 15:47:21
    这个我是应用到bmp文件中,然后在图像中任意画个四个点,最后平行四边形化,这个的重点 1、bmp的读取顺序,然后你的实际坐标和象素点上的坐标要对上的话,要反转。 2、四边形的平行四边化,这个比较简单,利用斜率法...
  • MFC格式的图形学设计内容:任意四边形的交、并、差操作,可供下载参考
  • 一、二维图形变化之基本知识 本章涉及向量、世界坐标系、用户坐标系、窗口与视区、齐次坐标、二维变换等 。需要掌握的知识点有: 向量、矩阵以及它们的运算 坐标系的概念和坐标系之间的变换齐次坐标的概念二维...
  • *以下技巧均源自于Lea Verou所著《CSSSecrets》 平行四边形 平行四边形的构造可以基于矩形通过skew()的变形属性进行斜向拉升得到(skew所用的坐标系,纵向是X轴,横向是Y轴...
  • 前言:在介绍四边形着色之前首先要提醒一下~openGL中对着色的四边形是默认以逆时针进行画边,然后再把形成的图形进行颜色填充,所以!如果描点的顺序不对的话,会形成不一样的图形。 1. 对三角形进行着色 GL_...
  • Illustrator 视频教程 主讲教师计算机与传媒系 朱丹妮 重庆电讯职业学院 计算机与传媒系 主讲教师朱丹妮 第13讲 简单编辑对象五 内容 重点学会使用自由变换工具制作透视变形效果 难点区分8种特殊变形工具各自不同的...
  • 找到一个最大的轮廓(四边形

    千次阅读 2018-05-21 23:20:43
    图片中有很多四边形和数字,我想只找到一个最大的四边形(或较大的),并得到他的顶点,然后进行透视变换,将图片变正,这是今天的程序暂存,目前对于一些函数还是不是很熟悉,明天再说。(在 drawContours(drawing,...
  • 对于了解3D图形学的人来说很清楚怎么用这些API绘制一个四边形,但对于刚入门的人来说,虽然只是多了一个点,但如果运气不好可能要费很大的劲。 我们知道stage3D API能绘制的最基本的图形元素是三角形,任何复杂的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,498
精华内容 1,799
关键字:

任意四边形图形