Marking.Template/App_Code/CommonUse.cs

1494 lines
53 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using Emgu.CV.Util;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
public class CommonUse
{
/// <summary>
/// 获取给定图像的最大矩形边界
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
public VectorOfVectorOfPoint GetBoundaryOfPic(Mat src)
{
Mat dst = new Mat();
Mat src_gray = new Mat();
CvInvoke.CvtColor(src, src_gray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
//边缘检测
CvInvoke.Canny(src_gray, dst, 20, 255, 3, true);
//寻找答题卡矩形边界(最大的矩形)
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();//创建VectorOfVectorOfPoint数据类型用于存储轮廓
CvInvoke.FindContours(dst, contours, null, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);//提取轮廓
VectorOfVectorOfPoint max_contour = new VectorOfVectorOfPoint();//用于存储筛选过后的轮廓
int ksize = contours.Size; //获取连通区域个数
if (ksize == 1)
{
max_contour = contours;
}
else
{
//double maxLength = -1;//用于保存轮廓周长的最大值
double maxArea = -1;//面积
int index = -1;//轮廓周长的最大值的序号
for (int i = 0; i < ksize; i++)
{
VectorOfPoint contour = contours[i];//获取独立的连通轮廓
//double length = CvInvoke.ArcLength(contour, true);//计算连通轮廓的周长
//if (length > maxLength)
//{
// maxLength = length;
// index = i;
//}
double area = CvInvoke.ContourArea(contour, false);
if (area > maxArea)
{
maxArea = area;
index = i;
}
}
max_contour.Push(contours[index]);//筛选后的连通轮廓
}
return max_contour;
}
/// <summary>
/// 进行透视操作,获取矫正后图像
/// </summary>
/// <param name="src"></param>
/// <param name="result_contour"></param>
public Mat MyWarpPerspective(Mat src, VectorOfVectorOfPoint max_contour)
{
//拟合答题卡的几何轮廓,保存点集pts并顺时针排序
VectorOfPoint pts = new VectorOfPoint();//用于存放逼近的结果
VectorOfPoint tempContour = max_contour[0];//临时用
double result_length = CvInvoke.ArcLength(tempContour, true);
CvInvoke.ApproxPolyDP(tempContour, pts, result_length * 0.02, true); //几何逼近获取矩形4个顶点坐标
if (pts.Size != 4)
{
//最大轮廓不是矩形时,将原图转灰度图后返回
Mat src_gray = new Mat();
CvInvoke.CvtColor(src, src_gray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);//转灰度图
return src_gray;
}
else
{
//Point[]转换为PointF[]类型
PointF[] pts_src = Array.ConvertAll(pts.ToArray(), new Converter<Point, PointF>(PointToPointF));
//点集顺时针排序
pts_src = SortPointsByClockwise(pts_src);
//确定透视变换的宽度、高度
Size sizeOfRect = CalSizeOfRect(pts_src);
int width = src.Bitmap.Width;
int height = src.Bitmap.Height;
//计算透视变换矩阵
PointF[] pts_target = new PointF[] { new PointF(0, 0), new PointF(width - 1, 0) ,
new PointF(width - 1, height - 1) ,new PointF(0, height - 1)};
//计算透视矩阵
Mat data = CvInvoke.GetPerspectiveTransform(pts_src, pts_target);
//进行透视操作
Mat src_gray = new Mat();
Mat mat_Perspective = new Mat();
CvInvoke.CvtColor(src, src_gray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
CvInvoke.WarpPerspective(src_gray, mat_Perspective, data, new Size(width, height));
return mat_Perspective;
}
}
/// <summary>
/// 根据给定XY初始坐标、间距、数量画网格
/// </summary>
/// <param name="mat"></param>
/// <param name="x"></param>
/// <param name="x_interval"></param>
/// <param name="x_num"></param>
/// <param name="y"></param>
/// <param name="y_interval"></param>
/// <param name="y_num"></param>
/// <returns></returns>
public Bitmap DrawGridByXYDraw(Bitmap bmp, int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num)
{
Mat src = new Image<Bgr, byte>(bmp).Mat;
//转换颜色空间
Mat mat_color = new Mat();
if (src.NumberOfChannels == 1)
CvInvoke.CvtColor(src, mat_color, Emgu.CV.CvEnum.ColorConversion.Gray2Bgr);
else
mat_color = src;
for (int i = 0; i <= x_num; i++)
{
//先画竖线
Point p1 = new Point(x_begin + x_interval * i, y_begin);
Point p2 = new Point(x_begin + x_interval * i, y_begin + y_interval * y_num);
CvInvoke.Line(mat_color, p1, p2, new MCvScalar(0, 0, 255), 2);
}
for (int i = 0; i <= y_num; i++)
{
//再画横线
Point p1 = new Point(x_begin, y_begin + y_interval * i);
Point p2 = new Point(x_begin + x_interval * x_num, y_begin + y_interval * i);
CvInvoke.Line(mat_color, p1, p2, new MCvScalar(0, 0, 255), 2);
}
return mat_color.Bitmap;
}
/// <summary>
/// 获取偏移量 通过矩形查找
/// </summary>
/// <param name="bmp"></param>
/// <param name="PointPath"></param>
/// <param name="PostionXY"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns></returns>
public Mat GetPostionXYByFindPostionAndXieLv(Mat color_mat, VectorOfVectorOfPoint selected_contours, string postionCut, out string PYPostion, Image<Gray, byte> currentFrame, out double xielv)
{
CommonUse commonUse = new CommonUse();
string[] postionc = postionCut.Split('^');
PYPostion = "";
Point GrXY;
int PostionWW = 0;
int PostionHH = 0;
int Y2 = 0, Y1 = 0, X2 = 0, X1 = 0;
for (int i = 0; i < postionc.Length; i++)
{
string[] postCutList = postionc[i].Split(',');
int X = Convert.ToInt32(Convert.ToDouble(postCutList[0]));
int Y = Convert.ToInt32(Convert.ToDouble(postCutList[1]));
int W = Convert.ToInt32(Convert.ToDouble(postCutList[2]));
int H = Convert.ToInt32(Convert.ToDouble(postCutList[3]));
string mx = "";
try
{
mx = commonUse.GetValueAndDrawGrid_Find(color_mat.Bitmap, selected_contours, X, W, 1, Y, H, 1, "", out GrXY);
}
catch
{
xielv = -100;
return null;
mx = "null";
GrXY = new Point(0, 0);
}
if (mx.Trim() != "A")
{
xielv = -100;
return null;
break;
}
Point Mx = GrXY;
if (i == 0)//左上角
{
PYPostion = GrXY.X + "," + GrXY.Y;
Y1 = GrXY.Y;
X1 = GrXY.X;
}
if (i == 1)//右上角
{
PostionWW = GrXY.X;
}
if (i == 2)//左下角
{
PostionHH = GrXY.Y;
X2 = GrXY.X;
Y2 = GrXY.Y;
}
}
string[] posList = PYPostion.Split(',');
xielv = Math.Atan2((Y2 - Y1), (X2 - X1)) * 180 / Math.PI;
int PostionX = Convert.ToInt32(posList[0]);
int PostionY = Convert.ToInt32(posList[1]);
int PostionW = PostionWW - PostionX;
int PostionH = PostionHH - PostionY;
//裁剪
Rectangle rectangle = new Rectangle(PostionX, PostionY, PostionW, PostionH);
Image<Gray, byte> Sub = new Image<Gray, byte>(currentFrame.Bitmap).GetSubRect(rectangle);
Image<Gray, byte> CropImage = new Image<Gray, byte>(Sub.Size);
CvInvoke.cvCopy(Sub, CropImage, IntPtr.Zero);
//获取偏移量
return CropImage.Mat;
}
/// <summary>
/// 将给定点集顺时针排序
/// </summary>
/// <param name="pts_src">四边形四个顶点组成的点集</param>
/// <returns></returns>
public PointF[] SortPointsByClockwise(PointF[] pts_src)
{
if (pts_src.Length != 4) return null;//确保为四边形
//求四边形中心点?坐标
float x_average = 0;
float y_average = 0;
float x_sum = 0;
float y_sum = 0;
for (int i = 0; i < 4; i++)
{
x_sum += pts_src[i].X;
y_sum += pts_src[i].Y;
}
x_average = x_sum / 4;
y_average = y_sum / 4;
PointF center = new PointF(x_average, y_average);
PointF[] result = new PointF[4];
for (int i = 0; i < 4; i++)
{
if (pts_src[i].X < center.X && pts_src[i].Y < center.Y)
{
result[0] = pts_src[i];//左上角点
continue;
}
if (pts_src[i].X > center.X && pts_src[i].Y < center.Y)
{
result[1] = pts_src[i];//右上角点
continue;
}
if (pts_src[i].X > center.X && pts_src[i].Y > center.Y)
{
result[2] = pts_src[i];//右下角点
continue;
}
if (pts_src[i].X < center.X && pts_src[i].Y > center.Y)
{
result[3] = pts_src[i];//左下角点
continue;
}
}
return result;
}
/// <summary>
/// 计算给定四个坐标点四边形的宽、高
/// </summary>
/// <param name="pts_src"></param>
/// <returns></returns>
public Size CalSizeOfRect(PointF[] pts_src)
{
if (pts_src.Length != 4) return new Size(0, 0);//确保为四边形
//点集顺时针排序
pts_src = SortPointsByClockwise(pts_src);
//确定透视变换的宽度、高度
int width;
int height;
double width1 = Math.Pow(pts_src[0].X - pts_src[1].X, 2) + Math.Pow(pts_src[0].Y - pts_src[1].Y, 2);
double width2 = Math.Pow(pts_src[2].X - pts_src[3].X, 2) + Math.Pow(pts_src[2].Y - pts_src[3].Y, 2);
width = width1 > width2 ? (int)Math.Sqrt(width1) : (int)Math.Sqrt(width2);//根号下a方+b方且取宽度最大的
double height1 = Math.Pow(pts_src[0].X - pts_src[3].X, 2) + Math.Pow(pts_src[0].Y - pts_src[3].Y, 2);
double height2 = Math.Pow(pts_src[1].X - pts_src[2].X, 2) + Math.Pow(pts_src[1].Y - pts_src[2].Y, 2);
height = height1 > height2 ? (int)Math.Sqrt(height1) : (int)Math.Sqrt(height2);
return new Size(width, height);
}
/// <summary>
/// Point转换为PointF类型
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public static PointF PointToPointF(Point p)
{
return new PointF(p.X, p.Y);
}
/// <summary>
/// 形态学膨胀
/// </summary>
/// <param name="mat"></param>
/// <returns></returns>
public Mat MyDilate(Mat mat)
{
//1.膨胀,改善轮廓
Mat struct_element = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Cross,
new Size(3, 3), new Point(-1, -1));//结构元素
Mat mat_dilate = new Mat();
CvInvoke.MorphologyEx(mat, mat_dilate, Emgu.CV.CvEnum.MorphOp.Dilate, struct_element, new Point(-1, -1), 1,
Emgu.CV.CvEnum.BorderType.Default, new MCvScalar(0, 0, 0));//形态学膨胀
return mat_dilate;
}
/// <summary>
/// 筛选图中符合给定条件的轮廓
/// </summary>
/// <param name="mat_threshold">要提取轮廓的图片</param>
/// <param name="width1">轮廓外接矩形大于该宽度值</param>
/// <param name="width2">轮廓外接矩形小于该宽度值</param>
/// <param name="height1">轮廓外接矩形大于该高度值</param>
/// <param name="height2">轮廓外接矩形小于该高度值</param>
public VectorOfVectorOfPoint GetUsefulContours(Mat mat, double ratio)
{
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();//所有的轮廓
VectorOfVectorOfPoint selected_contours = new VectorOfVectorOfPoint();//用于存储筛选过后的轮廓
CvInvoke.FindContours(mat, contours, null, Emgu.CV.CvEnum.RetrType.List,
Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);//提取所有轮廓,操作过程中会对输入图像进行修改
//筛选轮廓。筛选条件:长宽比大于给定值
for (int i = 0; i < contours.Size; i++)
{
Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);//外接矩形
Mat temp = new Mat(mat, rect);//提取ROI矩形区域
int pxNums = CvInvoke.CountNonZero(temp);//计算图像内非零像素个数
double area = CvInvoke.ContourArea(contours[i]);//计算连通轮廓的面积
double length = CvInvoke.ArcLength(contours[i], false); //计算连通轮廓的周长
VectorOfPoint approx_curve = new VectorOfPoint();//用于存放逼近的结果
CvInvoke.ApproxPolyDP(contours[i], approx_curve, length * 0.05, true);
bool bo = ((rect.Width > 8 && rect.Height > 3) && (area > 200 && area < 8000) && (rect.Width < 50 && rect.Height < 50) && pxNums > 100);
if (bo)
{
selected_contours.Push(contours[i]);
}
}
return selected_contours;
}
/// <summary>
/// 筛选图中符合给定条件的轮廓
/// </summary>
/// <param name="mat_threshold">要提取轮廓的图片</param>
/// <param name="width1">轮廓外接矩形大于该宽度值</param>
/// <param name="width2">轮廓外接矩形小于该宽度值</param>
/// <param name="height1">轮廓外接矩形大于该高度值</param>
/// <param name="height2">轮廓外接矩形小于该高度值</param>
public VectorOfVectorOfPoint GetUsefulContoursDingWei(Mat mat, double ratio)
{
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();//所有的轮廓
VectorOfVectorOfPoint selected_contours = new VectorOfVectorOfPoint();//用于存储筛选过后的轮廓
CvInvoke.FindContours(mat, contours, null, Emgu.CV.CvEnum.RetrType.List,
Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);//提取所有轮廓,操作过程中会对输入图像进行修改
//筛选轮廓。筛选条件:长宽比大于给定值
for (int i = 0; i < contours.Size; i++)
{
Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);//外接矩形
Mat temp = new Mat(mat, rect);//提取ROI矩形区域
int pxNums = CvInvoke.CountNonZero(temp);//计算图像内非零像素个数
double area = CvInvoke.ContourArea(contours[i]);//计算连通轮廓的面积
double length = CvInvoke.ArcLength(contours[i], false); //计算连通轮廓的周长
VectorOfPoint approx_curve = new VectorOfPoint();//用于存放逼近的结果
CvInvoke.ApproxPolyDP(contours[i], approx_curve, length * 0.02, true);
//外接矩形宽、高需在给定范围内
// bool bo = (rect.Width / rect.Height >= ratio && (rect.Width > 3 && rect.Height > 2) && (area > 200 && area <= 4500));
bool bo = ((rect.Width > 3 && rect.Height > 2) && (area > 100 && area <= 15000));
//bool bo = pxNums > 130 && pxNums < 300;
if (bo)
{
selected_contours.Push(contours[i]);
}
}
return selected_contours;
}
/// <summary>
/// 筛选图中符合给定条件的轮廓
/// </summary>
/// <param name="mat_threshold">要提取轮廓的图片</param>
/// <param name="width1">轮廓外接矩形大于该宽度值</param>
/// <param name="width2">轮廓外接矩形小于该宽度值</param>
/// <param name="height1">轮廓外接矩形大于该高度值</param>
/// <param name="height2">轮廓外接矩形小于该高度值</param>
public VectorOfVectorOfPoint GetUsefulContoursDingWeiSanJiao(Mat mat, double ratio)
{
VectorOfVectorOfPoint selected_contours = new VectorOfVectorOfPoint();
using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
{
// 参数:输入图像,点向量,,检索类型,方法
CvInvoke.FindContours(mat, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
for (int i = 0; i < contours.Size; i++)
{
using (VectorOfPoint contour = contours[i]) //点的标准矢量
using (VectorOfPoint approxContour = new VectorOfPoint())
{
// CvInvoke.ApproxPolyDP指定精度的多边形曲线 参数输入向量轮廓近似轮廓近似精度true则闭合形状
// CvInvoke.ArcLength计算轮廓长度 参数:轮廓,曲线是否闭合
CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.08, true); //0.08的相似度
//CvInvoke.ContourArea计算轮廓面积 参数:轮廓,返回值是否为绝对值
//仅考虑面积大于50的轮廓
if (CvInvoke.ContourArea(approxContour, false) > 500)
{
if (approxContour.Size == 3)//轮廓有3个顶点三角形
{
Point[] points = approxContour.ToArray(); //转化为数组
selected_contours.Push(contours[i]);
}
}
}
}
return selected_contours;
}
}
/// <summary>
/// 筛选图中符合给定条件的轮廓
/// </summary>
/// <param name="mat_threshold">要提取轮廓的图片</param>
/// <param name="width1">轮廓外接矩形大于该宽度值</param>
/// <param name="width2">轮廓外接矩形小于该宽度值</param>
/// <param name="height1">轮廓外接矩形大于该高度值</param>
/// <param name="height2">轮廓外接矩形小于该高度值</param>
public VectorOfVectorOfPoint GetUsefulContoursYueJuan(Mat mat, double ratio)
{
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();//所有的轮廓
VectorOfVectorOfPoint selected_contours = new VectorOfVectorOfPoint();//用于存储筛选过后的轮廓
CvInvoke.FindContours(mat, contours, null, Emgu.CV.CvEnum.RetrType.List,
Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);//提取所有轮廓,操作过程中会对输入图像进行修改
//筛选轮廓。筛选条件:长宽比大于给定值
for (int i = 0; i < contours.Size; i++)
{
Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);//外接矩形
Mat temp = new Mat(mat, rect);//提取ROI矩形区域
int pxNums = CvInvoke.CountNonZero(temp);//计算图像内非零像素个数
double area = CvInvoke.ContourArea(contours[i]);//计算连通轮廓的面积
double length = CvInvoke.ArcLength(contours[i], false); //计算连通轮廓的周长
VectorOfPoint approx_curve = new VectorOfPoint();//用于存放逼近的结果
CvInvoke.ApproxPolyDP(contours[i], approx_curve, length * 0.02, true);
//外接矩形宽、高需在给定范围内
bool bo = (rect.Width / rect.Height >= ratio && (rect.Width > 3 && rect.Height > 2) && (area > 200 && area <= 4500));
// bool bo = ((rect.Width > 3 && rect.Height > 2) && (area > 200 && area <= 4500));
//bool bo = ((rect.Width > 3 && rect.Height > 2) && (area > 200 && area <= 4500));
//bool bo = pxNums > 130 && pxNums < 300;
if (bo)
{
selected_contours.Push(contours[i]);
}
}
return selected_contours;
}
/// <summary>
/// 根据给定的轮廓及范围信息计算涂卡的结果返回int数组
/// </summary>
/// <param name="contours"></param>
/// <param name="x"></param>
/// <param name="x_interval"></param>
/// <param name="x_num"></param>
/// <param name="y"></param>
/// <param name="y_interval"></param>
/// <param name="y_num"></param>
/// <returns></returns>
public int[] GetTargetGravityFind(VectorOfVectorOfPoint contours, int x_begin, int x_interval, int x_num,
int y_begin, int y_interval, int y_num, out Point gravityXY)
{
int[] result = new int[x_num];//结果数组
//数组初值默认为-1
for (int i = 0; i < x_num; i++)
{
result[i] = -1;
}
int x_max = x_begin + x_interval * x_num;
int y_max = y_begin + y_interval * y_num;
VectorOfVectorOfPoint targetContours = new VectorOfVectorOfPoint();
Point[] gravity = GetGravityOfContours(contours);//轮廓中心点坐标
gravityXY = new Point(0, 0);
for (int i = 0; i < contours.Size; i++)
{
VectorOfPoint contour = contours[i];
if (gravity[i].X < x_begin || gravity[i].X > x_max || gravity[i].Y < y_begin || gravity[i].Y > y_max)
{
continue;//判断中心点是否超出范围
}
int x_id = (int)Math.Floor((double)(gravity[i].X - x_begin) / x_interval);//向下取整
int value = (int)Math.Floor((double)(gravity[i].Y - y_begin) / y_interval);
if (result[x_id] != -1)
{
string str = string.Format("第{0}列存在多个答案!请擦拭干净后再扫描", x_id);
result[x_id] = Convert.ToInt32(result[x_id].ToString() + value.ToString());
gravityXY = gravity[i];
}
else
{
Rectangle rect = CvInvoke.BoundingRectangle(contour);
//这里有修改
result[x_id] = value;
gravityXY = gravity[i];
gravityXY.X = rect.X;
gravityXY.Y = rect.Y;
break;
}
}
return result;
}
/// <summary>
/// 根据给定的轮廓及范围信息计算涂卡的结果返回int数组
/// </summary>
/// <param name="contours"></param>
/// <param name="x"></param>
/// <param name="x_interval"></param>
/// <param name="x_num"></param>
/// <param name="y"></param>
/// <param name="y_interval"></param>
/// <param name="y_num"></param>
/// <returns></returns>
public int[] GetTargetValues(VectorOfVectorOfPoint contours, int x_begin, int x_interval, int x_num,
int y_begin, int y_interval, int y_num)
{
int[] result = new int[x_num];//结果数组
//数组初值默认为-1
for (int i = 0; i < x_num; i++)
{
result[i] = -1;
}
int x_max = x_begin + x_interval * x_num;
int y_max = y_begin + y_interval * y_num;
VectorOfVectorOfPoint targetContours = new VectorOfVectorOfPoint();
Point[] gravity = GetGravityOfContours(contours);//轮廓中心点坐标
for (int i = 0; i < contours.Size; i++)
{
VectorOfPoint contour = contours[i];
if (gravity[i].X < x_begin || gravity[i].X > x_max || gravity[i].Y < y_begin || gravity[i].Y > y_max)
{
continue;//判断中心点是否超出范围
}
int x_id = (int)Math.Floor((double)(gravity[i].X - x_begin) / x_interval);//向下取整
int value = (int)Math.Floor((double)(gravity[i].Y - y_begin) / y_interval);
if (result[x_id] != -1)
{
string str = string.Format("第{0}列存在多个答案!请擦拭干净后再扫描", x_id);
//MessageBox.Show(x_id.ToString());
result[x_id] = Convert.ToInt32(result[x_id].ToString() + value.ToString());
//result[x_id] = -1;
}
else
{
result[x_id] = value;
}
}
return result;
}
/// <summary>
/// 根据给定的轮廓及范围信息计算涂卡的结果返回int数组
/// </summary>
/// <param name="contours"></param>
/// <param name="x"></param>
/// <param name="x_interval"></param>
/// <param name="x_num"></param>
/// <param name="y"></param>
/// <param name="y_interval"></param>
/// <param name="y_num"></param>
/// <returns></returns>
public int[] GetTargetValuesOnlyOne(VectorOfVectorOfPoint contours, int x_begin, int x_interval, int x_num,
int y_begin, int y_interval, int y_num)
{
int[] result = new int[x_num];//结果数组
//数组初值默认为-1
for (int i = 0; i < x_num; i++)
{
result[i] = -1;
}
int x_max = x_begin + x_interval * x_num;
int y_max = y_begin + y_interval * y_num;
VectorOfVectorOfPoint targetContours = new VectorOfVectorOfPoint();
Point[] gravity = GetGravityOfContours(contours);//轮廓中心点坐标
for (int i = 0; i < contours.Size; i++)
{
VectorOfPoint contour = contours[i];
if (gravity[i].X < x_begin || gravity[i].X > x_max || gravity[i].Y < y_begin || gravity[i].Y > y_max)
{
continue;//判断中心点是否超出范围
}
int x_id = (int)Math.Floor((double)(gravity[i].X - x_begin) / x_interval);//向下取整
int value = (int)Math.Floor((double)(gravity[i].Y - y_begin) / y_interval);
if (result[x_id] != -1)
{
//string str = string.Format("第{0}列存在多个答案!请擦拭干净后再扫描", x_id);
//MessageBox.Show(x_id.ToString());
//result[x_id] = Convert.ToInt32(result[x_id].ToString() + value.ToString());
//result[x_id] = -1;
}
else
{
result[x_id] = value;
}
}
return result;
}
// <summary>
/// 根据给定的轮廓及范围信息计算涂卡的结果返回int数组
/// </summary>
/// <param name="contours"></param>
/// <param name="x"></param>
/// <param name="x_interval"></param>
/// <param name="x_num"></param>
/// <param name="y"></param>
/// <param name="y_interval"></param>
/// <param name="y_num"></param>
/// <returns></returns>
public int[] GetTargetValues_L(VectorOfVectorOfPoint contours, int x_begin, int x_interval, int x_num,
int y_begin, int y_interval, int y_num)
{
int[] result = new int[y_num];//结果数组
//数组初值默认为-1
for (int i = 0; i < y_num; i++)
{
result[i] = -1;
}
int x_max = x_begin + x_interval * x_num;
int y_max = y_begin + y_interval * y_num;
VectorOfVectorOfPoint targetContours = new VectorOfVectorOfPoint();
Point[] gravity = GetGravityOfContours(contours);//轮廓中心点坐标
for (int i = 0; i < contours.Size; i++)
{
VectorOfPoint contour = contours[i];
if (gravity[i].X < x_begin || gravity[i].X > x_max || gravity[i].Y < y_begin || gravity[i].Y > y_max)
{
continue;//判断中心点是否超出范围
}
int x_id = (int)Math.Floor((double)(gravity[i].Y - y_begin) / y_interval);//向右取整数
int value = (int)Math.Floor((double)(gravity[i].X - x_begin) / x_interval);
if (result[x_id] != -1)
{
string str = string.Format("第{0}列存在多个答案!请擦拭干净后再扫描", x_id);
result[x_id] = Convert.ToInt32(result[x_id].ToString() + value.ToString());
}
else
{
result[x_id] = value;
}
}
return result;
}
// <summary>
/// 根据给定的轮廓及范围信息计算涂卡的结果返回int数组
/// </summary>
/// <param name="contours"></param>
/// <param name="x"></param>
/// <param name="x_interval"></param>
/// <param name="x_num"></param>
/// <param name="y"></param>
/// <param name="y_interval"></param>
/// <param name="y_num"></param>
/// <returns></returns>
public int[] GetTargetValues_L_only(VectorOfVectorOfPoint contours, int x_begin, int x_interval, int x_num,
int y_begin, int y_interval, int y_num)
{
int[] result = new int[y_num];//结果数组
//数组初值默认为-1
for (int i = 0; i < y_num; i++)
{
result[i] = -1;
}
int x_max = x_begin + x_interval * x_num;
int y_max = y_begin + y_interval * y_num;
VectorOfVectorOfPoint targetContours = new VectorOfVectorOfPoint();
Point[] gravity = GetGravityOfContours(contours);//轮廓中心点坐标
for (int i = 0; i < contours.Size; i++)
{
VectorOfPoint contour = contours[i];
if (gravity[i].X < x_begin || gravity[i].X > x_max || gravity[i].Y < y_begin || gravity[i].Y > y_max)
{
continue;//判断中心点是否超出范围
}
int x_id = (int)Math.Floor((double)(gravity[i].Y - y_begin) / y_interval);//向右取整数
int value = (int)Math.Floor((double)(gravity[i].X - x_begin) / x_interval);
if (result[x_id] != -1)
{
//string str = string.Format("第{0}列存在多个答案!请擦拭干净后再扫描", x_id);
//result[x_id] = Convert.ToInt32(result[x_id].ToString() + value.ToString());
}
else
{
result[x_id] = value;
}
}
return result;
}
/// <summary>
/// 画出网格并返回填图结果
/// </summary>
/// <param name="img"></param>
/// <param name="contours"></param>
/// <param name="x_begin">左边距</param>
/// <param name="x_interval">方块长度</param>
/// <param name="x_num">方块数量</param>
/// <param name="y_begin">上边距</param>
/// <param name="y_interval">方块高度</param>
/// <param name="y_num">方块竖数量</param>
/// <param name="strText">输出文字</param>
/// <returns></returns>
//public string GetValueAndDrawGridZhunKao(ImageBox img, VectorOfVectorOfPoint contours,
// int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText)
//{
// //画网格
// //Mat src = new Image<Bgr, byte>(img.Image.Bitmap).Mat;
// //Mat mat_grid = DrawGridByXY(img, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
// int[] intArray = GetTargetValues(contours, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
// int maxValue = GetMaxValueOfArray(intArray);//数组最大值
// string str = "";
// //str += Environment.NewLine;//回车
// str += strText;
// str += GetStringOfIntArray(intArray);
// return str;
//}
/// <summary>
/// 画出网格并返回填图结果
/// </summary>
/// <param name="img"></param>
/// <param name="contours"></param>
/// <param name="x_begin">左边距</param>
/// <param name="x_interval">方块长度</param>
/// <param name="x_num">方块数量</param>
/// <param name="y_begin">上边距</param>
/// <param name="y_interval">方块高度</param>
/// <param name="y_num">方块竖数量</param>
/// <param name="strText">输出文字</param>
/// <returns></returns>
public string GetValueAndDrawGridZhunKao(Bitmap img, VectorOfVectorOfPoint contours,
int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText)
{
//画网格
int[] intArray = GetTargetValuesOnlyOne(contours, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
int maxValue = GetMaxValueOfArray(intArray);//数组最大值
string str = "";
str += strText;
str += GetStringOfIntArray(intArray);
return str;
}
///// <summary>
///// 画出网格并返回填图结果
///// </summary>
///// <param name="img"></param>
///// <param name="contours"></param>
///// <param name="x_begin">左边距</param>
///// <param name="x_interval">方块长度</param>
///// <param name="x_num">方块数量</param>
///// <param name="y_begin">上边距</param>
///// <param name="y_interval">方块高度</param>
///// <param name="y_num">方块竖数量</param>
///// <param name="strText">输出文字</param>
///// <returns></returns>
//public string GetValueAndDrawGrid(ImageBox img, VectorOfVectorOfPoint contours,
// int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText)
//{
// //画网格
// //Mat src = new Image<Bgr, byte>(img.Image.Bitmap).Mat;
// //Mat mat_grid = DrawGridByXY(img, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
// int[] intArray = GetTargetValues(contours, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
// int maxValue = GetMaxValueOfArray(intArray);//数组最大值
// string str = "";
// //str += Environment.NewLine;//回车
// str += strText;
// if (maxValue >= 4 && maxValue <10)
// {
// str += GetStringOfIntArray(intArray);
// }
// else
// {
// if (maxValue >= 10)
// {
// str += GetStringOfIntArray(intArray, "ABCD");
// }
// else
// {
// str += GetStringOfIntArray(intArray, "ABCD");
// }
// }
// return str;
//}
/// <summary>
/// 画出网格并返回填图结果
/// </summary>
/// <param name="img"></param>
/// <param name="contours"></param>
/// <param name="x_begin">左边距</param>
/// <param name="x_interval">方块长度</param>
/// <param name="x_num">方块数量</param>
/// <param name="y_begin">上边距</param>
/// <param name="y_interval">方块高度</param>
/// <param name="y_num">方块竖数量</param>
/// <param name="strText">输出文字</param>
/// <returns></returns>
public string GetValueAndDrawGrid(Bitmap img, VectorOfVectorOfPoint contours,
int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText)
{
//画网格
// Mat mat_grid = DrawGridByXY(img, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
int[] intArray = GetTargetValuesOnlyOne(contours, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
int maxValue = GetMaxValueOfArray(intArray);//数组最大值
string str = "";
//str += Environment.NewLine;//回车
str += strText;
if (maxValue >= 4 && maxValue < 10)
{
str += GetStringOfIntArray(intArray, "ABCDEFG");
}
else
{
if (maxValue >= 10)
{
str += GetStringOfIntArray(intArray, "ABCDEFG");
}
else
{
str += GetStringOfIntArray(intArray, "ABCDEFG");
}
}
return str;
}
/// <summary>
/// 画出网格并返回填图结果
/// </summary>
/// <param name="img"></param>
/// <param name="contours"></param>
/// <param name="x_begin">左边距</param>
/// <param name="x_interval">方块长度</param>
/// <param name="x_num">方块数量</param>
/// <param name="y_begin">上边距</param>
/// <param name="y_interval">方块高度</param>
/// <param name="y_num">方块竖数量</param>
/// <param name="strText">输出文字</param>
/// <returns></returns>
public string GetValueAndDrawGrid_L(Bitmap img, VectorOfVectorOfPoint contours,
int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText)
{
//画网格
//Mat mat_grid = DrawGridByXY(img, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
int[] intArray = GetTargetValues_L_only(contours, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
int maxValue = GetMaxValueOfArray(intArray);//数组最大值
string str = "";
//str += Environment.NewLine;//回车
str += strText;
if (maxValue >= 4 && maxValue < 10)
{
str += GetStringOfIntArray(intArray, "ABCDEFG");
}
else
{
if (maxValue >= 10)
{
str += GetStringOfIntArray(intArray, "ABCDEFG");
}
else
{
str += GetStringOfIntArray(intArray, "ABCDEFG");
}
}
return str;
}
/// <summary>
/// 画出网格并返回填图结果
/// </summary>
/// <param name="img"></param>
/// <param name="contours"></param>
/// <param name="x_begin">左边距</param>
/// <param name="x_interval">方块长度</param>
/// <param name="x_num">方块数量</param>
/// <param name="y_begin">上边距</param>
/// <param name="y_interval">方块高度</param>
/// <param name="y_num">方块竖数量</param>
/// <param name="strText">输出文字</param>
/// <returns></returns>
public string GetValueAndDrawGrid_Find(Bitmap img, VectorOfVectorOfPoint contours,
int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText, out Point pFindX)
{
//画网格
Point pFind;
int[] intArray = GetTargetGravityFind(contours, x_begin, x_interval, x_num, y_begin, y_interval, y_num, out pFind);
int maxValue = GetMaxValueOfArray(intArray);//数组最大值
pFindX = pFind;
string str = "";
//str += Environment.NewLine;//回车
str += strText;
if (maxValue >= 4 && maxValue < 10)
{
str += GetStringOfIntArray(intArray);
}
else
{
if (maxValue >= 10)
{
str += GetStringOfIntArray(intArray, "ABCDEF");
}
else
{
str += GetStringOfIntArray(intArray, "ABCDEF");
}
}
return str;
}
/// <summary>
/// 画出网格并返回填图结果
/// </summary>
/// <param name="img"></param>
/// <param name="contours"></param>
/// <param name="x_begin">左边距</param>
/// <param name="x_interval">方块长度</param>
/// <param name="x_num">方块数量</param>
/// <param name="y_begin">上边距</param>
/// <param name="y_interval">方块高度</param>
/// <param name="y_num">方块竖数量</param>
/// <param name="strText">输出文字</param>
/// <returns></returns>
//public Mat GetDrawGrid(ImageBox img, VectorOfVectorOfPoint contours,
// int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText)
//{
// //画网格
// Mat mat_grid = DrawGridByXY(img, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
// return mat_grid;
//}
public Mat GetDrawGrid(Bitmap img, VectorOfVectorOfPoint contours,
int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText)
{
//画网格
Mat mat_grid = DrawGridByXY(img, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
return mat_grid;
}
///// <summary>
///// 画出网格并返回填图结果
///// </summary>
///// <param name="img"></param>
///// <param name="contours"></param>
///// <param name="x_begin">左边距</param>
///// <param name="x_interval">方块长度</param>
///// <param name="x_num">方块数量</param>
///// <param name="y_begin">上边距</param>
///// <param name="y_interval">方块高度</param>
///// <param name="y_num">方块竖数量</param>
///// <param name="strText">输出文字</param>
///// <returns></returns>
//public string GetValueAndDrawGridMore(ImageBox img, VectorOfVectorOfPoint contours,
// int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText)
//{
// //画网格
// //Mat src = new Image<Bgr, byte>(img.Image.Bitmap).Mat;
// //Mat mat_grid = DrawGridByXY(img, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
// int[] intArray = GetTargetValues(contours, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
// int maxValue = GetMaxValueOfArray(intArray);//数组最大值
// string str = "";
// str += strText;
// if (maxValue >= 7&& maxValue <10)
// {
// str += GetStringOfIntArray(intArray);
// }
// else
// {
// str += GetStringOfIntArray(intArray, "ABCDEFG");
// }
// return str;
//}
/// <summary>
/// 画出网格并返回填图结果
/// </summary>
/// <param name="img"></param>
/// <param name="contours"></param>
/// <param name="x_begin">左边距</param>
/// <param name="x_interval">方块长度</param>
/// <param name="x_num">方块数量</param>
/// <param name="y_begin">上边距</param>
/// <param name="y_interval">方块高度</param>
/// <param name="y_num">方块竖数量</param>
/// <param name="strText">输出文字</param>
/// <returns></returns>
public string GetValueAndDrawGridMore(Bitmap img, VectorOfVectorOfPoint contours,
int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText)
{
//画网格
//Mat src = new Image<Bgr, byte>(img.Image.Bitmap).Mat;
//Mat mat_grid = DrawGridByXY(img, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
int[] intArray = GetTargetValues(contours, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
int maxValue = GetMaxValueOfArray(intArray);//数组最大值
string str = "";
str += strText;
if (maxValue >= 7 && maxValue < 10)
{
str += GetStringOfIntArray(intArray);
}
else
{
str += GetStringOfIntArray(intArray, "ABCDEFG");
}
return str;
}
/// <summary>
/// 画出网格并返回填图结果
/// </summary>
/// <param name="img"></param>
/// <param name="contours"></param>
/// <param name="x_begin">左边距</param>
/// <param name="x_interval">方块长度</param>
/// <param name="x_num">方块数量</param>
/// <param name="y_begin">上边距</param>
/// <param name="y_interval">方块高度</param>
/// <param name="y_num">方块竖数量</param>
/// <param name="strText">输出文字</param>
/// <returns></returns>
public string GetValueAndDrawGridMoreL(Bitmap img, VectorOfVectorOfPoint contours,
int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num, string strText)
{
//画网格
//Mat mat_grid = DrawGridByXY(img, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
int[] intArray = GetTargetValues_L(contours, x_begin, x_interval, x_num, y_begin, y_interval, y_num);
int maxValue = GetMaxValueOfArray(intArray);//数组最大值
string str = "";
str += strText;
if (maxValue >= 7 && maxValue < 10)
{
str += GetStringOfIntArray(intArray);
}
else
{
str += GetStringOfIntArray(intArray, "ABCDEFG");
}
return str;
}
/// <summary>
/// 计算轮廓中心点坐标
/// </summary>
/// <param name="selected_contours">要计算中心点的轮廓</param>
/// <returns></returns>
public Point[] GetGravityOfContours(VectorOfVectorOfPoint selected_contours)
{
int ksize = selected_contours.Size;
double[] m00 = new double[ksize];
double[] m01 = new double[ksize];
double[] m10 = new double[ksize];
Point[] gravity = new Point[ksize];//用于存储轮廓中心点坐标
MCvMoments[] moments = new MCvMoments[ksize];
for (int i = 0; i < ksize; i++)
{
VectorOfPoint contour = selected_contours[i];
//计算当前轮廓的矩
moments[i] = CvInvoke.Moments(contour, false);
m00[i] = moments[i].M00;
m01[i] = moments[i].M01;
m10[i] = moments[i].M10;
int x = Convert.ToInt32(m10[i] / m00[i]);//计算当前轮廓中心点坐标
int y = Convert.ToInt32(m01[i] / m00[i]);
gravity[i] = new Point(x, y);
}
return gravity;
}
///// <summary>
///// 根据给定XY初始坐标、间距、数量画网格
///// </summary>
///// <param name="mat"></param>
///// <param name="x"></param>
///// <param name="x_interval"></param>
///// <param name="x_num"></param>
///// <param name="y"></param>
///// <param name="y_interval"></param>
///// <param name="y_num"></param>
///// <returns></returns>
//public Mat DrawGridByXY(ImageBox img, int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num)
//{
// Mat src = new Image<Bgr, byte>(img.Image.Bitmap).Mat;
// //转换颜色空间
// Mat mat_color = new Mat();
// if (src.NumberOfChannels == 1)
// CvInvoke.CvtColor(src, mat_color, Emgu.CV.CvEnum.ColorConversion.Gray2Bgr);
// else
// mat_color = src;
// for (int i = 0; i <= x_num; i++)
// {
// //先画竖线
// Point p1 = new Point(x_begin + x_interval * i, y_begin);
// Point p2 = new Point(x_begin + x_interval * i, y_begin + y_interval * y_num);
// CvInvoke.Line(mat_color, p1, p2, new MCvScalar(0, 0, 255), 1);
// }
// for (int i = 0; i <= y_num; i++)
// {
// //再画横线
// Point p1 = new Point(x_begin, y_begin + y_interval * i);
// Point p2 = new Point(x_begin + x_interval * x_num, y_begin + y_interval * i);
// CvInvoke.Line(mat_color, p1, p2, new MCvScalar(0, 0, 255), 1);
// }
// img.Image = mat_color;
// return mat_color;
//}
/// <summary>
/// 根据给定XY初始坐标、间距、数量画网格
/// </summary>
/// <param name="mat"></param>
/// <param name="x"></param>
/// <param name="x_interval"></param>
/// <param name="x_num"></param>
/// <param name="y"></param>
/// <param name="y_interval"></param>
/// <param name="y_num"></param>
/// <returns></returns>
public Mat DrawGridByXY(Bitmap img, int x_begin, int x_interval, int x_num, int y_begin, int y_interval, int y_num)
{
Mat src = new Image<Bgr, byte>(img).Mat;
//转换颜色空间
Mat mat_color = new Mat();
if (src.NumberOfChannels == 1)
CvInvoke.CvtColor(src, mat_color, Emgu.CV.CvEnum.ColorConversion.Gray2Bgr);
else
mat_color = src;
for (int i = 0; i <= x_num; i++)
{
//先画竖线
Point p1 = new Point(x_begin + x_interval * i, y_begin);
Point p2 = new Point(x_begin + x_interval * i, y_begin + y_interval * y_num);
CvInvoke.Line(mat_color, p1, p2, new MCvScalar(0, 0, 255), 1);
}
for (int i = 0; i <= y_num; i++)
{
//再画横线
Point p1 = new Point(x_begin, y_begin + y_interval * i);
Point p2 = new Point(x_begin + x_interval * x_num, y_begin + y_interval * i);
CvInvoke.Line(mat_color, p1, p2, new MCvScalar(0, 0, 255), 1);
}
//img.Image = mat_color;
return mat_color;
}
/// <summary>
/// 画出给定轮廓
/// </summary>
/// <param name="mat"></param>
/// <param name="contours"></param>
/// <returns></returns>
public Mat DrawContours(Mat mat, VectorOfVectorOfPoint contours)
{
//转换颜色空间
Mat mat_color = new Mat();
CvInvoke.CvtColor(mat, mat_color, Emgu.CV.CvEnum.ColorConversion.Gray2Bgr);
CvInvoke.DrawContours(mat_color, contours, -1, new MCvScalar(255, 0, 0), 2);
return mat_color;
}
/// <summary>
/// 拼接给定int数组内容并返回拼接后字符串
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
public string GetStringOfIntArray(int[] arr)
{
string str = "";
foreach (int a in arr)
{
str += a.ToString() + "";
}
return str;
}
/// <summary>
/// 拼接给定int数组内容并返回拼接后字符串
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
public string GetStringOfIntArray(int[] arr, string ss = "ABCD")
{
string str = "";
//char[] ch = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
char[] ch = ss.ToCharArray();
foreach (int a in arr)
{
///
if (a >= 10)
{
string x = a.ToString();
char[] cc = x.ToArray();
int[] result = new int[cc.Length];
for (int i = 0; i < cc.Length; i++)
{
result[i] = Convert.ToInt32(x.Substring(i, 1));
}
Array.Sort(result);
int[] finalResult = result;
for (int j = 0; j < finalResult.Length; j++)
{
if (finalResult[j] == -1)
{
str += "null";
}
else
{
str += ch[finalResult[j]];
}
}
str += " ";
}
else
{
if (a == -1)
{
str += "null ";//未识别时,标示为空
}
else
{
str += ch[a] + " ";
}
}
}
return str;
}
/// <summary>
/// 获取一维int数组中最大值
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
public int GetMaxValueOfArray(int[] arr)
{
int[] dst = new int[arr.Length];
Array.Copy(arr, dst, arr.Length);//深度复制数组,防止排序对原数组产生影响
Array.Sort(dst);//数组排序
int maxValue = dst[arr.Length - 1];//数组最大值
return maxValue;
}
/// <summary>
/// 显示图像,并等待按下任意按键后继续
/// </summary>
/// <param name="title"></param>
/// <param name="mat"></param>
/// <param name="zoomRatio"></param>
public void ShowMatWaitKey(string title, Mat mat, double zoomRatio)
{
CvInvoke.Resize(mat, mat, new Size(), zoomRatio, zoomRatio, Inter.Cubic);
CvInvoke.Imshow(title, mat);
CvInvoke.WaitKey(0);
}
public Bitmap RotateByOrientation(Bitmap bitmap)
{
// 获取图片的方向信息并根据方向调整图片
if (bitmap.PropertyIdList.Contains(0x0112))
{
var orientation = (int)bitmap.GetPropertyItem(0x0112).Value[0];
switch (orientation)
{
case 2:
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX);
break;
case 3:
bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
break;
case 4:
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
break;
case 5:
bitmap.RotateFlip(RotateFlipType.Rotate90FlipX);
break;
case 6:
bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
break;
case 7:
bitmap.RotateFlip(RotateFlipType.Rotate270FlipX);
break;
case 8:
bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
break;
}
}
return bitmap;
}
}
public class ZhuguantiList
{
public int QuestionSmallNum
{
get; set;
}
public Bitmap btm
{
get; set;
}
public string num
{
get; set;
}
}
public class otherBitmaplist
{
public Bitmap btm
{
get; set;
}
public string Text
{
get; set;
}
}