// 根据坐标和小图大小截取Bitmap. public static Bitmap CutPic(String strFile, Location location, mySize size) { Bitmap bitRtn = new Bitmap(size.ROW, size.COL); Image image = Image.FromFile(strFile); // 抛出 内存不足错误 Bitmap bitmap = new Bitmap(image); Color c = new Color(); for (int i = 0; i < size.ROW; i++) //整幅图像行(高) { for (int j = 0; j < size.COL; j++) //整幅图像列(宽) { // GetPixel 函数在读取元素时,行列是反着的 c = bitmap.GetPixel(j + location.column, i + location.row);//获取图片每个点灰度 // 新的图片里必须做偏移运算 bitRtn.SetPixel(j, i, c); } } // new出来地方处理掉. bitmap.Dispose(); return(bitRtn); }
// 其中一个构造函数,用于在一个大矩阵中切割小矩阵 // 参数是起始位置 // 参数是一个原始大矩阵和需要切割的height和width public Matrix( double[,] D, Location location, mySize size ) { data = new double[size.ROW, size.COL]; // 根据开始位置开始读取值 int height = size.ROW; int width = size.COL; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { // 从开始点向右和向下 切割矩阵 // 在大矩阵中寻找需要切割的元素坐标 int SplitRow = location.row + i; int SplitColumn = location.column + j; data[i, j] = D[SplitRow, SplitColumn]; } } //return data; }
// 获得小图在大图中的匹配数量 public static mySize GetPiPeiSize(Matrix MBig, Matrix MSmall) { int iNewRow = MBig.Row - MSmall.Row + 1; int iNewCol = MBig.Column - MSmall.Column + 1; mySize sizeRtn = new mySize(iNewRow, iNewCol); return(sizeRtn); }
// 2个矩阵匹配,输出一个匹配结果 public static Matrix PiPei(Matrix MSmall, Matrix MBig) { // 算出新的匹配矩阵的大小 // 小矩阵在大的矩阵上移动 int iNewRow = MBig.Row - MSmall.Row + 1; int iNewCol = MBig.Column - MSmall.Column + 1; Matrix Mrtn = new Matrix(iNewRow, iNewCol); int iSmallRow = MSmall.Row; int iSmallCol = MSmall.Column; int offsetValue = 1; // 偏移指针 Location baseL = new Location(0, 0); mySize size = new mySize(iSmallRow, iSmallCol); // 小匹配图大小 for (int i = 0; i < iNewRow; i++) { // Big bug // i没有做偏移. baseL.row = i * offsetValue; for (int j = 0; j < iNewCol; j++) { // 每次在大基准图切割一个和匹配小图一样大小的图 // 然后和匹配小图进行运算得到一个值 // 输出到矩阵的位置 // 切割. // 在内循环中,首地址一直向右移动1个单元 // 在每一行中,一列一列的循环 // 偏移指针, 首地址向右根据当前小矩阵j来移动 // 比如 第一个地址为(0,0) 第二个为(0,1) baseL.column = j * offsetValue; // 每次偏移一个像素位置 Matrix baseM = new Matrix(MBig.data, baseL, size); // 比较. double dRtn = CompareMatrix(baseM, MSmall); // 放置值. Mrtn.data[i, j] = dRtn; } } return(Mrtn); }
/// <summary> /// 从文件获取Row和Col /// </summary> /// <param name="strFile"></param> /// <returns></returns> public static mySize GetSize(string strFile) { mySize size = new mySize(0, 0); Image imageTemp = Image.FromFile(strFile); // 根据事实设定 size.ROW = imageTemp.Height; size.COL = imageTemp.Width; imageTemp.Dispose(); return(size); }
/// <summary> /// 获得图片的Row和Colomn值 /// </summary> /// <param name="strBase">文件名字</param> /// <returns>返回mySize对象</returns> private mySize GetPicSize(string strFile) { mySize sizeRtn = new mySize(0, 0); // 用一个Image. Image image = Image.FromFile(strFile); // 这里会开辟新内存 Bitmap bitmap = new Bitmap(image); // 如果是Tif 没有RGB分量 不用经过灰度图转换 sizeRtn.COL = image.Width; sizeRtn.ROW = image.Height; // 释放资源 bitmap.Dispose(); image.Dispose(); return(sizeRtn); }
public static Location HandlePoint(Location curL, byte[,] bCsharp, mySize size) { // 只对Point里的 行和列值做越界判断,然后改变这个值 Location LRtn = new Location(); LRtn.row = curL.row; LRtn.column = curL.column; // 行 // 内框右边的值 int nSmallRow = curL.row + size.ROW - 1; // 外框的坐标值 int nOutRow = bCsharp.GetLength(0) - 1; if (nSmallRow > nOutRow) { // Row 越界 外框矩阵坐标 - 矩阵长度 + 1 int nReturnRow = nOutRow - size.ROW + 1; LRtn.row = nReturnRow; } // 列 // 内框右边的值 int nSmallCol = curL.column + size.COL - 1; // 外框的坐标值 int nOutCol = bCsharp.GetLength(1) - 1; if (nSmallCol > nOutCol) { // Row 越界 外框矩阵坐标 - 矩阵长度 + 1 int nReturnCol = nOutCol - size.COL + 1; LRtn.column = nReturnCol; } return(LRtn); }
// 输入一个大矩阵,返回以8*8基本矩阵为基础的嵌套矩阵 public static Matrix[,] SplitMatrix(double[,] PicBase, mySize SmallBaseSize) { Matrix[,] mRtn = null; // 判断需要开辟多大的矩阵 int iBaseSize = SmallBaseSize.ROW; int iBigSize = PicBase.GetLength(0); int nNeed = iBigSize / iBaseSize; mRtn = new Matrix[nNeed, nNeed]; // 切割矩阵的控制代码,先写死 速度做出来 Location baseL = new Location(0, 0); for (int i = 0; i < nNeed; i++) { // 在外循环中,首地址一直向下移动8个单元 // 便利循环下一列 baseL.row = i * iBaseSize; for (int j = 0; j < nNeed; j++) { // 在内循环中,首地址一直向右移动8个单元 // 在每一行中,一列一列的循环 // 偏移指针, 首地址向右根据当前小矩阵j来移动 // 比如 第一个地址为(0,0) 第二个为(0,8) baseL.column = j * 8; Matrix eachM = new Matrix(PicBase, baseL, SmallBaseSize); mRtn[i, j] = eachM; } } return(mRtn); }
public void Run() { // Console.WriteLine("Hello World!"); int nSetThread = 7; // 先完成一个配置项 // 一个BasePic和一个目录=》 txt匹配结果 //String strBasePic = ""; //String StrDir = ""; // 先完成单个基础匹配策略. // 一个BasePic和一个MatchPic => txt匹配结果 //String strBase = "../../../BasePics/ccd.tif"; //String strMatch = "../../../IR_Report/IR_256_256_20/Pic/ir_256_256_0_0.tif"; String strBase = "../../../BasePics/ccd3.tif"; String strMatch = "../../../IR3_Report/IR3_256_256_20/Pic/ir3_256_256_0_0.tif"; // 提取文件的Row和Col组合 String fileLocation = GetLocationForm(strMatch); // 按照层次位置读取文件. mySize BaseSize = GetPicSize(strBase); double[,] PicBase = new double[BaseSize.ROW, BaseSize.COL]; mySize matchSize = GetPicSize(strMatch); double[,] PicMatch = new double[matchSize.ROW, matchSize.COL]; // 把图片数字设置到分配的内存里 SetPicData(strBase, PicBase); SetPicData(strMatch, PicMatch); // 计算移动一个像素点时 需要匹配的次数. MatrixCiCui nPiPeiSize = GetPiPeiTime(PicMatch, PicBase); // 为每个线程对象分配 区域匹配任务. // 计算是否单独多设置一个线程 int HandleUnitNUM = GetThreadNum(nSetThread, nPiPeiSize); List <HandleUnit> HUnitList = new List <HandleUnit>(); for (int i = 0; i < HandleUnitNUM; i++) { HandleUnit hu = new HandleUnit(); HUnitList.Add(hu); } // 为每一个处理单元分配区域. 这里的值只是个数,从0计数 int TotalNum = nPiPeiSize.horSize * nPiPeiSize.verSize; int baseTask = TotalNum / nSetThread; for (int i = 0; i < HandleUnitNUM; i++) { HandleUnit each = HUnitList[i]; each.nStart = i * baseTask; each.nEnd = each.nStart + baseTask - 1; // 设置最后一个特殊值. if (each.nEnd > (TotalNum - 1)) { each.nEnd = TotalNum - 1; } each.mBasePic = PicBase; each.mMatchPic = PicMatch; each.mPiPeiSize = nPiPeiSize; } //设置线程. List <Thread> threadList = new List <Thread>(); for (int i = 0; i < HandleUnitNUM; i++) { Thread HandleThread; // 发送数据的线程对象. HandleUnit each = HUnitList[i]; HandleThread = new Thread(new ThreadStart(each.Matching)); threadList.Add(HandleThread); } // 同时启动线程 for (int i = 0; i < HandleUnitNUM; i++) { Thread each = threadList[i]; each.Start(); } Console.WriteLine("Here"); bool bExit = false; while (false == bExit) { bExit = CheckStop(threadList); } // 在分线程全部做完操作后 还可以整合资源 // 从HUnitList里找出最大的值 并输出文件结果 // 组合集合. Hashtable TotalHT = GetTotalHT(HUnitList); Location lResult = GetLocation(TotalHT); // Console.WriteLine("{0},{1}",lResult.row,lResult.column); // 写文件. String strLog = "TestLog.txt"; //WriteLog(lResult, strMatch, strLog); Console.ReadLine(); }
public String myRun(String strBase, String strMatch, int nSetThread) { String strRtn = string.Empty; // 提取文件的Row和Col组合 String fileLocation = GetLocationForm(strMatch); // 按照层次位置读取文件. mySize BaseSize = GetPicSize(strBase); double[,] PicBase = new double[BaseSize.ROW, BaseSize.COL]; mySize matchSize = GetPicSize(strMatch); double[,] PicMatch = new double[matchSize.ROW, matchSize.COL]; // 把图片数字设置到分配的内存里 SetPicData(strBase, PicBase); SetPicData(strMatch, PicMatch); // 计算移动一个像素点时 需要匹配的次数. MatrixCiCui nPiPeiSize = GetPiPeiTime(PicMatch, PicBase); // 为每个线程对象分配 区域匹配任务. // 计算是否单独多设置一个线程 int HandleUnitNUM = GetThreadNum(nSetThread, nPiPeiSize); List <HandleUnit> HUnitList = new List <HandleUnit>(); for (int i = 0; i < HandleUnitNUM; i++) { HandleUnit hu = new HandleUnit(); HUnitList.Add(hu); } // 为每一个处理单元分配区域. 这里的值只是个数,从0计数 int TotalNum = nPiPeiSize.horSize * nPiPeiSize.verSize; int baseTask = TotalNum / nSetThread; for (int i = 0; i < HandleUnitNUM; i++) { HandleUnit each = HUnitList[i]; each.nStart = i * baseTask; each.nEnd = each.nStart + baseTask - 1; // 设置最后一个特殊值. if (each.nEnd > (TotalNum - 1)) { each.nEnd = TotalNum - 1; } each.mBasePic = PicBase; each.mMatchPic = PicMatch; each.mPiPeiSize = nPiPeiSize; } //设置线程. List <Thread> threadList = new List <Thread>(); for (int i = 0; i < HandleUnitNUM; i++) { Thread HandleThread; // 发送数据的线程对象. HandleUnit each = HUnitList[i]; HandleThread = new Thread(new ThreadStart(each.Matching)); threadList.Add(HandleThread); } // 同时启动线程 for (int i = 0; i < HandleUnitNUM; i++) { Thread each = threadList[i]; each.Start(); } Console.WriteLine("Here"); bool bExit = false; while (false == bExit) { bExit = CheckStop(threadList); } // 在分线程全部做完操作后 还可以整合资源 // 从HUnitList里找出最大的值 并输出文件结果 // 组合集合. Hashtable TotalHT = GetTotalHT(HUnitList); Location lResult = GetLocation(TotalHT); String strLo = string.Format("{0},{1}", lResult.row, lResult.column); // 写文件. 文件内容. strRtn = string.Format("{0} {1}", fileLocation, strLo); // 文件名字 大图+小图+小图位置. String StrLogName = GetLogName(strBase, strMatch, fileLocation); WriteLog(strRtn, StrLogName); return(strRtn); }
// Copy数据 从一部分拷贝 public static void CopyMatrixValue(byte[,] whiteIR, byte[,] ccd, Location TopLeft, mySize SmallSize) { // 循环遍历 int nRow = SmallSize.ROW; int nCol = SmallSize.COL; for (int i = 0; i < nRow; i++) { for (int j = 0; j < nCol; j++) { int nCurRow = i + TopLeft.row; int nCurCol = j + TopLeft.column; whiteIR[nCurRow, nCurCol] = ccd[nCurRow, nCurCol]; } } }
// 根据图片的i和j的值, 大图大小和小图大小, 获得左上角坐标值 public static Location GetTopLeftLocation(int nRowSmall, int nColSmall, mySize BigSize, mySize SmallSize, byte[,] bCsharp) { Location lRtn = new Location(0, 0); //Math.Ceiling(3.1) = 4; //Math.Floor(3.9) = 3; // 行数为0 列数为1 Height为行数 Width为列数 int iBigRow = BigSize.ROW; int iBigCol = BigSize.COL; double iSmallRow = Convert.ToDouble(SmallSize.ROW); double iSmallCol = Convert.ToDouble(SmallSize.COL); int iSplitHeight = Convert.ToInt32(Math.Ceiling(iBigRow / iSmallRow)); int iSplitWidth = Convert.ToInt32(Math.Ceiling(iBigCol / iSmallCol)); // 基准点参考值 偏移指针 Location curL = new Location(0, 0); mySize size = new mySize(SmallSize.ROW, SmallSize.COL); // 循环遍历, 分割出矩阵后,直接输出小文件 // 需要分割的矩阵数量已经计算好 for (int i = 0; i < iSplitHeight; i++) { curL.row = i * SmallSize.ROW; for (int j = 0; j < iSplitWidth; j++) { // 类似10*10的矩阵 [0,0] [0,10] [0,] // [0,0] [0,10] [0,20] // [10,0] [10,10] [10,20] // [20,0] [20,10] [20,20] curL.column = j * SmallSize.COL; // 输入偏移指针,返回一个左上角坐标值 // 有异常情况 需要调整位置,都在这个函数里处理 Location handlePoint = HandlePoint(curL, bCsharp, size); // 获得byte小矩阵 // byte[,] bSmall = GetSmallM(handlePoint, bCsharp, size); if ((nRowSmall == i) && (nColSmall == j)) { // 输出左上角坐标. lRtn.row = handlePoint.row; lRtn.column = handlePoint.column; return(lRtn); } } } return(lRtn); }
// 输入两个矩阵List, 输出一个匹配矩阵 public static Matrix PiPeiMatrix(List <Matrix> MBiglist, List <Matrix> MSmalist, Location[] Lvector) { // MBiglist * * 12 // MSmalist * * 12 // MFinallist * * 12 int nVector = Lvector.Length; // 小图在大图上做移动匹配 List <Matrix> MFinallist = new List <Matrix>(); double dE = 0.0; for (int z = 0; z < nVector; z++) { //mylist[i].name Matrix MBig = MBiglist[z]; Matrix MSmall = MSmalist[z]; ABSMatrix(MBig); ABSMatrix(MSmall); // 输入2个矩阵,导出一个矩阵. Matrix Mfinal = PiPei(MSmall, MBig); ABSMatrix(Mfinal); // 从Mfinal中找个最大值和第二大值 double dMax = FindMax(Mfinal); double dSecondMax = FindSecondMax(Mfinal); // 算出主峰与次峰比值 double dBiZhi = dMax / dSecondMax; // 得出一个新矩阵 MatrixMulti(Mfinal, dBiZhi); // 记录新矩阵 MFinallist.Add(Mfinal); // 记录主次峰比值 dE = dE + dBiZhi; } // dE 之后会用到 nVector = MFinallist.Count; // GetPiPeiSize mySize PiPeiSize = GetPiPeiSize(MBiglist[0], MSmalist[0]); Matrix MaxtrixSum = new Matrix(PiPeiSize.ROW, PiPeiSize.COL); for (int i = 1; i < nVector; i++) { Matrix eachM = MFinallist[i]; // 求和 MaxtrixAdd(MaxtrixSum, eachM); } // 矩阵除法 Matrix MatrixG = MaxtrixDiv(MaxtrixSum, dE); return(MatrixG); }