基于Emgucv,C#的图片旋转方式
程序员文章站
2022-07-06 11:39:43
方法调用: ......
1 /// <summary> 2 /// 图片旋转 --百度 旋转仿射 3 /// </summary> 4 /// <param name="modelimage"></param> 5 /// <param name="degree"></param> 6 /// <returns></returns> 7 image<bgra, byte> rotateimage1(image modelimage, int degree) 8 { 9 image<bgra, byte> modelimage_emgucv = new image<bgra, byte>(new bitmap(modelimage)); 10 double angle = degree * math.pi / 180; // 弧度 11 double a = math.sin(angle), b = math.cos(angle); 12 int width = modelimage.width; 13 int height = modelimage.height; 14 int width_rotate = convert.toint32(height * math.abs(a) + width * math.abs(b)); 15 int height_rotate = convert.toint32(width * math.abs(a) + height * math.abs(b)); 16 //旋转数组map 17 // [ m0 m1 m2 ] ===> [ a11 a12 b1 ] 18 // [ m3 m4 m5 ] ===> [ a21 a22 b2 ] 19 //float[] map = new float[6]; 20 //此处为修改点,opencv可以直接使用数组,但emgucv似乎不认,所以改为了matrix。 21 matrix<float> map_matrix_temp = new matrix<float>(2, 3); 22 23 // 旋转中心 24 pointf center = new pointf(width / 2, height / 2); 25 cvinvoke.getrotationmatrix2d(center, degree, 1.0, map_matrix_temp); 26 27 map_matrix_temp[0, 2] += (width_rotate - width) / 2; 28 map_matrix_temp[1, 2] += (height_rotate - height) / 2; 29 30 image<bgra, byte> img_rotate = new image<bgra, byte>(width_rotate, height_rotate, new bgra(0d, 0d, 0d, 0d)); 31 32 //对图像做仿射变换 33 //cv_warp_fill_outliers - 填充所有输出图像的象素。 34 //如果部分象素落在输入图像的边界外,那么它们的值设定为 fillval. 35 //cv_warp_inverse_map - 指定 map_matrix 是输出图像到输入图像的反变换, 36 cvinvoke.warpaffine(modelimage_emgucv, img_rotate, map_matrix_temp, new size(width_rotate, height_rotate), inter.nearest, warp.default, bordertype.transparent, new mcvscalar(0d, 0d, 0d, 0d)); 37 38 return img_rotate; 39 }
1 /// <summary> 2 /// 图像的旋转 3 /// 在 image<tcolor,tdepth>rotate 有三个重载函数, 这边简单介绍: 4 /// public image<tcolor, tdepth> rotate(double angle, tcolor background); 5 /// public image<tcolor, tdepth> rotate(double angle, tcolor background, boolcrop); 6 /// public image<tcolor, tdepth> rotate(double angle, pointf center, inter interpolationmethod, tcolor background, bool crop); 7 ///参数解析: 8 /// double angle: 顺时针旋转角度。 9 /// pointf center: 旋转中心, 默认为图像的中心。 10 /// inter interpolationmethod: 插值类型表示符, 如表 6.1 所示。 11 /// tcolor background: 背景图像的颜色, tcolor 类型与图像的颜色 12 /// 类型一致。 13 /// bool crop: 如果 crop = true, 则图像裁剪到与原来图像一样大,可能会失去边角信息。 14 ///false, 保证不失去边角信息, 但是改变了图像的大小。 默认为 true。 15 /// </summary> 16 public image<bgra, byte> imagerotates(bitmap map,double dou,bool bol=false) 17 { 18 image<bgra, byte> imga1 = new image<bgra, byte>(map); 19 //image<bgra, byte> imga2 = imga1.rotate(dou, new bgra(0, 0, 0, 0), bol); 20 // image<bgra, byte> imga2 = imga1.rotate(dou, new bgra(0, 0, 0, 0), bol) 等同于 21 image<bgra, byte> imga2 = imga1.rotate(dou, new pointf(imga1.width / 2, imga1.height / 2), inter.cubic, new bgra(0, 0, 0, 0), bol); 22 return imga2; 23 24 }
1 /// <summary> 2 /// 三点仿射实现代码 3 /// </summary> 4 /// <param name="map"></param> 5 /// <param name="dou"></param> 6 /// <returns></returns> 7 public mat imagepointfs(bitmap map, double dou) 8 { 9 image<bgra, byte> imga1 = new image<bgra, byte>(map); 10 //image<bgra, byte> imga2 = new image<bgra, byte>(map); 11 pointf[] scr = new pointf[] { new pointf(0, 0), new pointf(90, 0),new pointf(0, 90) };//创建用于获取仿射矩阵的原始三个点的坐标。 12 pointf[] dst = new pointf[] { new pointf(0, 0), new pointf(0, 90), new pointf(90, 0) };//创建用于获取仿射矩阵的目标三个点的坐标。 13 mat data = new mat();//创建矩阵, 用于存储仿射矩阵。 14 15 data = cvinvoke.getaffinetransform(scr, dst);//获取仿射矩阵。 16 17 mat scr_mat = imga1.mat;//创建矩阵, 用于存储原始图像(输入图像)。 18 mat dst_mat = new mat();//创建矩阵, 用于存储目标图像(处理后的图像)。 19 //scr_mat = new mat("flower.jpg",emgu.cv.cvenum.imreadmodes.anycolor);//指定目录实例化一张图像。 20 //image<bgra, byte> img_rotate = new image<bgra, byte>(imga1.width, imga1.height, new bgra(0d, 0d, 0d, 0d)); 21 cvinvoke.warpaffine(scr_mat, dst_mat, data, new size(scr_mat.height, scr_mat.width));//采用仿射获取目标图像。 22 //imagebox1.image = scr_mat;//显示原始图像。 23 //imagebox2.image = dst_mat;//显示目标图像。 24 return dst_mat; 25 26 }
1 /// <summary> 2 /// 旋转仿射 3 /// </summary> 4 /// <param name="map"></param> 5 /// <param name="dou"></param> 6 /// <returns></returns> 7 public mat imagerume(bitmap map, double dou) 8 { 9 image<bgra, byte> imga1 = new image<bgra, byte>(map); 10 mat data = new mat();//创建矩阵, 用于存储旋转矩阵。 11 //double angle = dou * math.pi / 180; // 弧度 12 cvinvoke.getrotationmatrix2d(new pointf(imga1.width/2, imga1.height / 2), dou, 1, data);//以特定的参数获取旋转矩阵。 13 mat scr_mat = imga1.mat;//创建矩阵, 用于存储原始图像(输入图 像)。 14 mat dst_mat = new mat();//创建矩阵, 用于存储目标图像(处理后的图像)。 15 //scr_mat = new mat("flower.jpg",emgu.cv.cvenum.loadimagetype.anycolor);//指定目录实例化一张图像。 16 17 //warp.filloutliers 向左 18 //warp.inversemap 向右 19 cvinvoke.warpaffine(scr_mat, dst_mat, data, scr_mat.size, inter.nearest, warp.default, bordertype.transparent, new mcvscalar(0d, 0d, 0d, 0d));// 采 用 仿射获取目标图像。 20 21 return dst_mat; 22 23 }
方法调用:
1 private void button1_click(object sender, eventargs e) 2 { 3 image img = bit; 4 image<bgra, byte> image = null; 5 if (radiobutton1.checked) 6 image = rotateimage1(img, int.parse(numericupdown1.value.tostring())); 7 if (radiobutton2.checked) 8 image = imagerotates(bit, double.parse(numericupdown1.value.tostring())); 9 if (radiobutton3.checked) 10 image = new image<bgra, byte>(imagepointfs(bit, double.parse(numericupdown1.value.tostring())).bitmap); 11 if (radiobutton4.checked) 12 image = new image<bgra, byte>(imagerume(bit, double.parse(numericupdown1.value.tostring())).bitmap); 13 14 15 if (image != null) 16 { 17 picturebox1.image = image.bitmap; 18 } 19 20 image<bgra, byte> imae = new image<bgra, byte>(bit); 21 cvinvoke.imshow("原图", imae); 22 23 }
上一篇: 用vue 实现手机触屏滑动功能
下一篇: C# 输入一个整数,求质因数