//图像二值化 private static int[,] BinMap(Bitmap image, InterpreProBar iterprePB) { iterprePB.Show(); int[,] idata = new int[image.Width, image.Height]; //存储像元值,用于计算 for (int x = 0; x < image.Width; x++) { iterprePB.SetProgressValue(x); for (int y = 0; y < image.Height; y++) { Color pixelColor = image.GetPixel(x, y); idata[x, y] = (pixelColor.R + pixelColor.G + pixelColor.B) / 3; if (idata[x, y] != 0) { idata[x, y] = 0; } else { idata[x, y] = 1; } } } iterprePB.Close(); return(idata); }
private void VarCal_Click(object sender, EventArgs e) { if (tBoxImportData.Text == "" || tBoxExportResult.Text == "") { MessageBox.Show("请输入完整的参数和存储路径!", "逐行提取对象大小"); return; //退出函数 } Bitmap image = new Bitmap(tBoxImportData.Text, true); //读入图片 InterpreProBar iterprePB = new InterpreProBar(0, image.Width); //数据解析进度 int[,] idata = BinMap(image, iterprePB); // 二值化 //提取每行的元素 计算:地物和背景的均值/方差 地物均值/方差 背景均值/方差 double[] bavg = new double[image.Height];//存储每行背景的均值 double[] oavg = new double[image.Height]; double[] bvar = new double[image.Height];//存储每行背景的方差 double[] ovar = new double[image.Height]; double[] OBvar = new double[image.Height]; //存储每行的方差 double[] OBavg = new double[image.Height]; //存储每行的均值 double[] cyclevar = new double[image.Height]; //存储每行的方差 double[] cycleavg = new double[image.Height]; //存储每行的均值 CacuProBar progressForm = new CacuProBar("逐行方差均值计算", 0, image.Height); //计算进度 progressForm.Show(); //开始显示计算进度 for (int i = 0; i < image.Height; i++) //逐行计算 { progressForm.SetProgressValue(i); int[] obasize = objBacSizeLine(i, idata); int bcnt = 0, ocnt = 0; double bsum = 0; double osum = 0; double OBsum = 0; //分别计算地物和背景的方差均值 for (int j = 0; j < obasize.Length; j++) { OBsum += obasize[j]; if (idata[0, i] == 0) //如果第一个是背景 0 010101010 { if (j % 2 == 0) //偶数下标就是背景bac长度 { bsum += obasize[j]; bcnt++; } else //奇数数下标就是地物obj长度 { osum += obasize[j]; ocnt++; } } else //如果第一个是背景 1 101010101 { if (j % 2 == 0) //偶数下标就是地物obj长度 { osum += obasize[j]; ocnt++; } else { bsum += obasize[j]; bcnt++; } } } progressForm.Close(); OBavg[i] = OBsum / (bcnt + ocnt); bavg[i] = bsum / bcnt; oavg[i] = osum / ocnt; double os = 0; //obj均值与数组元素值得差的平方和 double bs = 0; //bac均值与数组元素值得差的平方和 double OBs = 0; //bac均值与数组元素值得差的平方和 //计算地物和背景的方差 for (int j = 0; j < obasize.Length; j++) { OBs += Math.Pow(obasize[j] - OBavg[i], 2); if (idata[0, i] == 0) //如果第一个是背景 0 { if (j % 2 == 0) { bs += Math.Pow(obasize[j] - bavg[i], 2); } else { os += Math.Pow(obasize[j] - oavg[i], 2); } } else ////如果第一个是地物 1 { if (j % 2 == 0) { os += Math.Pow(obasize[j] - oavg[i], 2); } else { bs += Math.Pow(obasize[j] - bavg[i], 2); } } } OBvar[i] = OBs / (bcnt + ocnt); bvar[i] = bs / bcnt; ovar[i] = os / ocnt; //计算黑白周期长度的均值和方差 for (int j = 0; j < obasize.Length; j++) { if (idata[0, i] == 0) //如果第一个是背景 0 { if (j % 2 == 0) { bs += Math.Pow(obasize[j] - bavg[i], 2); } else { os += Math.Pow(obasize[j] - oavg[i], 2); } } else ////如果第一个是地物 1 { if (j % 2 == 0) { os += Math.Pow(obasize[j] - oavg[i], 2); } else { bs += Math.Pow(obasize[j] - bavg[i], 2); } } } } String str = tBoxExportResult.Text; //写出计算结果 if (str.Substring(str.LastIndexOf('.'), 3 + 1) == ".txt")//包头不包尾 { saveCacuResultAsText(tBoxExportResult.Text, bavg, bvar, oavg, ovar, OBavg, OBvar); } else { saveCacuResultAsExcel(tBoxExportResult.Text, bavg, bvar, oavg, ovar, OBavg, OBvar); } MessageBox.Show("OK,计算和保存完成!", "逐行提取对象大小"); this.Dispose(); }
int maxlag; //最大变异距离 private void VarCal_Click(object sender, EventArgs e) { if (tBoxImportData.Text == "" || cbxVarOrg.Text == "" || cbBMaxLag.Text == "" || tBLag.Text == "" || tBoxExportResult.Text == "") { MessageBox.Show("请输入完整的参数和存储路径!", "逐行变异计算"); return; //退出函数 } image = new Bitmap(tBoxImportData.Text, true); //读入图片 int[,] idata = new int[image.Width, image.Height]; //存储像元值,用于计算 switch (cbBMaxLag.Text) { case "1/2图幅": maxlag = image.Width / 2; //参数lag 为变异距离 break; case "1/4图幅": maxlag = image.Width / 4; //参数lag 为变异距离 break; case "1/8图幅": maxlag = image.Width / 8; //参数lag 为变异距离 break; default: maxlag = image.Width / 2; //参数lag 为变异距离 break; } //存储逐行变异值 double[,] dResult = new double[image.Height, maxlag]; string[,] sResult = new string[image.Height, maxlag]; //存储全幅变异值 double [] dMResult = new double[maxlag]; InterpreProBar iterprePB = new InterpreProBar(0, image.Width); //数据解析进度 idata = BinMap(image, iterprePB); // 二值化 //输出二值图像二值数据 string datapath = tBoxBinMap.Text; //存储路径 if (radioButtonYes.Checked) { saveBinMap(idata, datapath, image); } //变异计算 CacuProBar progressForm = new CacuProBar("变异计算", 0, maxlag); //变异计算进度 progressForm.Show(); //开始显示计算进度 for (int h = 1; h < maxlag; h++) //变异滞后距离 { progressForm.SetProgressValue(h); //全幅计算 int cn = 0; //记录运算次数 double sum = 0; //滞后距离差的平方和 if (cbxVarMapOrLine.Text.Trim() == "全幅") { if (cbxVarOrg.Text == "W-->E") { for (int row = 0; row < image.Height; row++) ////窗口大小与图像行列数关系 { for (int col = 0; col < image.Width - h; col++) ////窗口大小与图像行列数关系 { sum += Math.Pow((idata[row, col] - idata[row, col + h]), 2); cn = cn + 1; } } } if (cbxVarOrg.Text == "N-->S") { } if (cbxVarOrg.Text == "WS-->EN") { } if (cbxVarOrg.Text == "WN-->ES") { } dMResult[h] = sum / (2 * cn); } else if (cbxVarMapOrLine.Text == "逐行") //单行横向计算 { if (cbxVarOrg.Text == "W-->E") { double n = 0; //计算次数 ArrayList p = new ArrayList(); //以h为滞后距离的差的平方 for (int j = 0; j < image.Height; ++j) //每行变异 { double pp = 0; //差的平方的和 for (int i = 0; i < image.Width - h; i++) //最大变异宽幅 { p.Add(Math.Pow(idata[i, j] - idata[i + h, j], 2)); pp += (Double)p[i]; //将h为滞后距离的差的平方相加 } p.Clear(); n = image.Width - h; dResult[j, h] = pp / (2 * n); } } if (cbxVarOrg.Text == "N-->S") { } if (cbxVarOrg.Text == "WS-->EN") { } if (cbxVarOrg.Text == "WN-->ES") { } } } progressForm.Close(); //写出计算结果 if (cbxVarMapOrLine.Text == "逐行") { //平滑消除小波动 smoothSemiVar(dResult, Convert.ToInt32(cbxSmoothWindowSize.Text)); //提取变异前5个峰值和谷值 double[,] semiPeekMax = new double[image.Height, 5]; double[,] semiPeekMin = new double[image.Height, 5]; //提取峰值所在的索引 int[,] semiPeekMaxIndex = new int[image.Height, 5]; int[,] semiPeekMinIndex = new int[image.Height, 5]; semiPeekMax = getSemiVarPeekMax(dResult); semiPeekMin = getSemiVarPeekMin(dResult); semiPeekMaxIndex = getSemiVarPeekMaxIndex(dResult); semiPeekMinIndex = getSemiVarPeekMinIndex(dResult); saveLineCacuResultAsText(tBoxExportResult.Text, dResult, semiPeekMaxIndex, semiPeekMinIndex, semiPeekMax, semiPeekMin); } else if (cbxVarMapOrLine.Text == "全幅") { saveMapCacuResultAsText(tBoxExportResult.Text, dMResult); } MessageBox.Show("变异计算完成!", "变异计算"); this.Dispose(); }
private void VarCal_Click(object sender, EventArgs e) { if (tBoxImportData.Text == "" || cbxVarOrg.Text == "" || tBoxExportResult.Text == "") { MessageBox.Show("请输入完整的参数和存储路径!", "逐行方差计算"); return; //退出函数 } image = new Bitmap(tBoxImportData.Text, true); //读入图片 int x, y; int[,] idata = new int[image.Width, image.Height]; //存储像元值,用于计算 string[,] sdata = new string[image.Width, image.Height]; //存储像元值,用于写出 InterpreProBar iterprePB = new InterpreProBar(0, image.Width); //数据解析进度 iterprePB.Show(); // 二值化 for (x = 0; x < image.Width; x++) { iterprePB.SetProgressValue(x); for (y = 0; y < image.Height; y++) { Color pixelColor = image.GetPixel(x, y); idata[x, y] = (pixelColor.R + pixelColor.G + pixelColor.B) / 3; if (idata[x, y] != 0) { idata[x, y] = 0; } else { idata[x, y] = 1; } } } iterprePB.Close(); avg = new double[idata.GetLength(1)]; var2 = new double[idata.Length];//存储每行的方差 //逐行方差计算 for (int line = 0; line < idata.GetLength(0); line++) { double sum = 0;//均值与数组元素值得差的平方和 avg[line] = average2D(idata, line); for (int j = 0; j < idata.GetLength(1); j++) { sum += Math.Pow(idata[line, j] - avg[line], 2); } var2[line] = sum / idata.GetLength(1); } //结果输出变异结果 string path = tBoxExportResult.Text; //存储路径 using (FileStream fs = File.Create(path)) { AddText(fs, "行号 均值 方差 \r\n"); for (int i = 0; i < idata.GetLength(0); i++) { AddText(fs, String.Format("{0,6:D6}", i) + " " + String.Format("{0:N6}", avg[i]) + " " + String.Format("{0:N6}", var2[i]) + "\r\n "); } } MessageBox.Show("逐行方差计算完成!", "方差计算"); this.Dispose(); }