public ActionResult DeleteConfirmed(string id) { KM kM = db.KmS.Find(id); db.KmS.Remove(kM); db.SaveChanges(); return(RedirectToAction("Index")); }
public ActionResult Edit([Bind(Include = "MaKhuyenMai,PhanTram")] KM kM) { if (ModelState.IsValid) { db.Entry(kM).State = EntityState.Modified; db.SaveChanges(); return(RedirectToAction("Index")); } return(View(kM)); }
void Awake() { if (instance == null) { instance = this; } else if (instance != this) { Destroy(gameObject); } }
public ActionResult Create([Bind(Include = "MaKhuyenMai,PhanTram")] KM kM) { if (ModelState.IsValid) { db.KmS.Add(kM); db.SaveChanges(); return(RedirectToAction("Index")); } return(View(kM)); }
/// <summary> /// /// </summary> /// <param name="image"></param> /// <returns></returns> public bool CreateImage(KM.JXC.DBA.Image image) { bool result = false; using (KuanMaiEntities db = new KuanMaiEntities()) { db.Image.Add(image); db.SaveChanges(); result = true; } return result; }
// GET: KMs/Delete/5 public ActionResult Delete(string id) { if (id == null) { return(new HttpStatusCodeResult(HttpStatusCode.BadRequest)); } KM kM = db.KmS.Find(id); if (kM == null) { return(HttpNotFound()); } return(View(kM)); }
public ActionResult Checkout(ShippingDetail detail) { var hoaDon = this.Session["Receipt"] as Receipt; if (hoaDon != null) { hoaDon.ReceiptDetails = db.ReceiptDetails.Where(x => x.ReceiptID == hoaDon.ReceiptID).ToList(); if (ModelState.IsValid) { KM voucher = db.KmS.Where(x => x.MaKhuyenMai == detail.VoucherString).FirstOrDefault(); if (detail.VoucherString != null) { hoaDon.TotalCost = hoaDon.TotalCost * (1 - voucher.PhanTram / 100); } StringBuilder body = new StringBuilder() .AppendLine("A new order has been submitted") .AppendLine("---") .AppendLine("Items:"); foreach (var hoaDonChiTiet in hoaDon.ReceiptDetails) { var subtotal = hoaDonChiTiet.SanPhamObj.Gia * hoaDonChiTiet.Total; body.AppendFormat("{0} x {1} (subtotal: {2:c}", hoaDonChiTiet.Total, hoaDonChiTiet.SanPhamObj.Ten, subtotal); } body.AppendFormat("Total order value: {0:c}", hoaDon.TotalCost) .AppendLine("---") .AppendLine("Ship to:") .AppendLine(detail.Name) .AppendLine(detail.Address) .AppendLine(detail.Mobile.ToString()); this.Session["Receipt"] = null; hoaDon.Status = 1; db.SaveChanges(); return(View("CheckoutCompleted")); } else { return(View(new ShippingDetail())); } } else { return(View("NoItem")); } }
public string GetDisplayValue(xfMileUnit mileUnit) { switch (mileUnit) { case xfMileUnit.Yard: return(string.Format("{0}ML{1}YD", KM.ToString("0000"), M.ToString("0000"))); case xfMileUnit.KM_MACType2: return(string.Format("{0}km{1}dm", KM.ToString("0000"), M.ToString("0000"))); case xfMileUnit.KMOther: return(string.Format("{0}km{1}m", KM.ToString("0000"), (M / 10).ToString("000"))); default: throw new NotImplementedException(); } }
public override void Draw(SpriteBatch spriteBatch) { switch (displayIndex) { case 0: spriteBatch.Draw(Logo, new Vector2((Singleton.Instance.Diemensions.X - Logo.Width) / 2, (Singleton.Instance.Diemensions.Y - Logo.Height) / 2), _Color); break; case 1: fontSize = Arcanista.MeasureString("proudly present"); spriteBatch.DrawString(Arcanista, "proudly present", new Vector2((Singleton.Instance.Diemensions.X - fontSize.X) / 2, (Singleton.Instance.Diemensions.Y - fontSize.Y) / 2), _Color); break; case 2: fontSize = KM.MeasureString("Egypt Bubble"); spriteBatch.DrawString(KM, "Egypt Bubble", new Vector2((Singleton.Instance.Diemensions.X - fontSize.X) / 2, (Singleton.Instance.Diemensions.Y - fontSize.Y) / 2), _Color); break; case 3: spriteBatch.Draw(Black, Vector2.Zero, _Color); break; } }
public void Run() { double totaltime = 0; int s = 100, K = 100, m = 100; string[] templatefiles = Directory.GetFiles(@"D:\Play Data\train_data\scq-" + K + "-" + m, "*.scq") .Take(20000).ToArray(); string[] templateSCfiles = Directory.GetFiles(@"D:\Play Data\train_data\sc\", "*.sc") .Take(20000).ToArray(); #region 打开量化的模板 int templatecount = templatefiles.Length; Debug("打开{0}个量化模板----------------------------------------", templatecount); timer.Restart(); int[][] templatehistograms = new int[templatecount][]; int[] templatenums = new int[templatecount]; for (int f = 0; f < templatecount; ++f) { string file = templatefiles[f]; string filename = Path.GetFileNameWithoutExtension(file); templatenums[f] = int.Parse(filename.Split('-')[1]); templatehistograms[f] = new int[K]; using (var fs = new FileStream(file, FileMode.Open)) { using (var br = new BinaryReader(fs)) { for (int i = 0; i < K; ++i) { templatehistograms[f][i] = br.ReadInt32(); } } } } Debug("打开完成,用时{0}ms.", timer.Stop()); #endregion #region 打开Shapeme Debug("打开{0}个Shapeme.", K); timer.Restart(); double[][] shapemes = new double[K][]; using (var fs = new FileStream(Path.Combine(@"D:\Play Data\train_data\sm-" + K, m + ".sm"), FileMode.Open)) { using (var br = new BinaryReader(fs)) { for (int i = 0; i < K; ++i) { shapemes[i] = new double[60]; for (int k = 0; k < 60; ++k) { shapemes[i][k] = br.ReadDouble(); } } } } Debug("Shapeme读取完成,用时{0}ms.", timer.Stop()); #endregion string[] testfiles = Directory.GetFiles(@"D:\Play Data\test\", "*.bmp") .Take(1000).ToArray(); #region 测试 int testcase = testfiles.Length, acc = 0; Debug("为{0}个对象寻找候选模板------------------------------------------", testcase); foreach (var file in testfiles) { timer.Restart(); #region 计算待测图的形状上下文 string filenameext = Path.GetFileName(file); string filename = Path.GetFileNameWithoutExtension(file); int thisnum = int.Parse(filename.Split('-')[1]); Image<Gray, Byte> img = new Image<Gray, byte>(file); var list = getEdge(img.Resize(2.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR)).Sample(s); var sc = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC2(list); var sc2 = new double[s, 60]; for (int i = 0; i < s; ++i) { for (int j = 0; j < 60; ++j) { sc2[i, j] = sc[i][j]; } } #endregion #region 对待测图的形状上下文进行量化 int[] histogram = new int[K]; for (int i = 0; i < s; ++i) { double[] ds = new double[K]; for (int j = 0; j < K; ++j) ds[j] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(sc[i], shapemes[j]); int id = ds.Select((v, idx) => new ValueIndexPair<double> { Value = v, Index = idx }) .OrderBy(p => p.Value) .First().Index; ++histogram[id]; } #endregion #region 计算量化后的比较距离 double[] dists = new double[templatecount]; for (int i = 0; i < templatecount; ++i) { dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.ChiSquareDistance(histogram, templatehistograms[i]); //dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(histogram.Cast<double>().ToArray(), templatehistograms[i].Cast<double>().ToArray()); } #endregion #region 对结果进行排序和统计 var arr = dists.Select((d, i) => new ValueIndexPair<double> { Value = d, Index = i }) .OrderBy(p => p.Value); int knn = 10; #endregion #region 进行精细匹配 var kmresults = new List<ValueIndexPair<double>>(); foreach (var pair in arr.Take(knn)) { int idx = pair.Index; var scfile = templateSCfiles[idx]; // var sci = new double[s][]; var sci = new double[s, 60]; using (var fs = new FileStream(scfile, FileMode.Open)) { using (var br = new BinaryReader(fs)) { for (int j = 0; j < s; ++j) { //sci[j] = new double[60]; for (int k = 0; k < 60; ++k) { //sci[j][k] = br.ReadDouble(); sci[j, k] = br.ReadDouble(); } } } } var costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(sci, sc2); var costmat_int = new int[s, s]; for (int ii = 0; ii < s; ++ii) { for (int jj = 0; jj < s; ++jj) { costmat_int[ii, jj] = (int)(costmat[ii, jj] * 10000); } } var km = new KM(s, costmat_int); km.Match(false); kmresults.Add(new ValueIndexPair<double> { Index = idx, Value = km.MatchResult / 10000.0 }); } kmresults.Sort((a, b) => a.Value.CompareTo(b.Value)); #endregion //int firstmatch = match[0].Num; int firstmatch = templatenums[kmresults[0].Index]; var fc = Console.ForegroundColor; Console.ForegroundColor = firstmatch == thisnum ? ConsoleColor.Green : ConsoleColor.Red; var timeused = timer.Stop(); totaltime += timeused; string info = String.Format("{0} {1}ms\t", filename, timeused); //foreach (var m in bestmatches.Take(4)) { foreach (var mmm in kmresults.Take(4)) { info += String.Format("{0}/{1:F2}\t", templatenums[mmm.Index], mmm.Value); } //Debug(info); if (firstmatch != thisnum) Console.Write("."); Console.ForegroundColor = fc; if (firstmatch == thisnum) { ++acc; } } Debug("\nShapeme and KM 测试用例:{0}。正确率{1}。", testcase, acc); Console.WriteLine("总用时:{0}ms,平均用时:{1}ms。", totaltime, totaltime / testcase); #endregion }
public double MatchIteration(Matrix X, Matrix Y, Matrix V1, Matrix V2, Matrix t1, Matrix t2) { timer.Clear(); double timeused = 0; timer.Restart(); var tk = t1.Clone(); // tk=t1; int w = 4; int ndum = (int)(nsamp * ndum_frac); nsamp1 = nsamp2 = nsamp; #region demo2迭代 Matrix Xk = X.Clone(); int N1 = V1.Rows, N2 = V2.Columns; if (display_flag) { Draw(X, Y, V1, V2, @"D:\Play Data\Iteration\原图.bmp", "原始图像和采样"); //DrawGradient(X, Y, t1, t2, N2, N1, @"D:\Play Data\Iteration\原图梯度.bmp", "原始图像切向量"); } int k = 0; var out_vec_1 = Utils.InitArray<bool>(nsamp1, false);//out_vec_1=zeros(1,nsamp1); var out_vec_2 = Utils.InitArray<bool>(nsamp2, false);//out_vec_2=zeros(1,nsamp2); double ori_weight = 0.1; double tan_eps = 1.0; bool affine_start_flag = true; bool polarity_flag = true; double matchcost = double.MaxValue; double sc_cost = 0, aff_cost = 0, E = 0; Matrix cx = null, cy = null; // cx, cy是插值线性方程组的解的两列 Matrix axt = null, wxt = null, ayt = null, wyt = null, d2 = null, U = null, X2 = null, Y2 = null, X2b = null, X3b = null, Y3 = null; double mean_dist_1 = 0, mean_dist_2 = 0; var min1 = new[] { new { Val = 0.0, Idx = 0 } }; var min2 = min1; #region 用于打网格的坐标 Matrix coordX = null, coordY = null; int coordMargin = (int)(N1 * coordMarginRate); MatrixUtils.CreateGrid(N1 + coordMargin * 2, N2 + coordMargin * 2, out coordX, out coordY); coordX = coordX.Each(v => v - coordMargin * 2); coordY = coordY.Each(v => v - coordMargin * 2); //int MM = N1 * N2 / 25; // M=length(x); #endregion timeused += timer.StopAndSay("初始化"); while (k < n_iter) { Debug("Iter={0}", k); #region 计算两个形状上下文 timer.Restart(); // [BH1,mean_dist_1]=sc_compute(Xk',zeros(1,nsamp),mean_dist_global,nbins_theta,nbins_r,r_inner,r_outer,out_vec_1); var BH1 = ComputeSC(Xk.Transpose(), Zeros(1, nsamp), mean_dist_global, out mean_dist_1, out_vec_1); //var BH1 = ComputeSC(Xk.Transpose(), t1.Transpose(), mean_dist_global, out mean_dist_1, out_vec_1); // [BH2,mean_dist_2]=sc_compute(Y',zeros(1,nsamp),mean_dist_global,nbins_theta,nbins_r,r_inner,r_outer,out_vec_2); var BH2 = ComputeSC(Y.Transpose(), Zeros(1, nsamp), mean_dist_global, out mean_dist_2, out_vec_2); //var BH2 = ComputeSC(Y.Transpose(), t2.Transpose(), mean_dist_global, out mean_dist_2, out_vec_2); timeused += timer.StopAndSay("计算两个形状上下文"); Debug("Mean_dist_1:{0:F4}", mean_dist_1); Debug("Mean_dist_2:{0:F4}", mean_dist_2); #endregion #region 计算lambda_o和beta_k double lambda_o; if (affine_start_flag) { if (k == 0) lambda_o = 1000; else lambda_o = beta_init * Math.Pow(r, k - 1); // lambda_o=beta_init*r^(k-2); } else { lambda_o = beta_init * Math.Pow(r, k); // lambda_o=beta_init*r^(k-1); } double beta_k = mean_dist_2 * mean_dist_2 * lambda_o; #endregion #region 计算代价矩阵 timer.Restart(); var costmat_shape = HistCost(BH1, BH2); // costmat_shape = hist_cost_2(BH1, BH2); // theta_diff=repmat(tk,1,nsamp)-repmat(t2',nsamp,1); var theta_diff = tk.RepMat(1, nsamp) - t2.Transpose().RepMat(nsamp, 1); Matrix costmat_theta; if (polarity_flag) { // costmat_theta=0.5*(1-cos(theta_diff)); //costmat_theta = 0.5 * (Ones(costmat_shape.Rows, costmat_shape.Columns) - theta_diff.Each(v => Math.Cos(v))); costmat_theta = theta_diff.Each(v => 0.5 * (1 - Math.Cos(v))); } else { // costmat_theta=0.5*(1-cos(2*theta_diff)); //costmat_theta = 0.5 * (Ones(costmat_shape.Rows, costmat_shape.Columns) - theta_diff.Each(v => Math.Cos(2 * v))); costmat_theta = theta_diff.Each(v => 0.5 * (1 - Math.Cos(2 * v))); } // costmat=(1-ori_weight)*costmat_shape+ori_weight*costmat_theta; var costmat = (1 - ori_weight) * costmat_shape + ori_weight * costmat_theta; int nptsd = nsamp + ndum; // nptsd=nsamp+ndum; var costmat2 = new DenseMatrix(nptsd, nptsd, eps_dum); // costmat2=eps_dum*ones(nptsd,nptsd); costmat2.SetSubMatrix(0, nsamp, 0, nsamp, costmat); // costmat2(1:nsamp,1:nsamp)=costmat; timeused += timer.StopAndSay("计算代价矩阵"); #endregion #region 匈牙利算法 timer.Restart(); var costmat_int = new int[nptsd, nptsd]; for (int i = 0; i < nptsd; ++i) { for (int j = 0; j < nptsd; ++j) { costmat_int[i, j] = (int)(costmat2[i, j] * 10000); } } var km = new KM(nptsd, costmat_int); km.Match(false); matchcost = km.MatchResult / 10000.0; int[] cvec = km.MatchPair; // cvec=hungarian(costmat2); timeused += timer.StopAndSay("匈牙利算法"); #endregion #region 计算野点标记向量,重排匹配点 timer.Restart(); int[] cvec2 = cvec.Select((v, i) => new { Val = v, Idx = i }) .OrderBy(v => v.Val) .Select(v => v.Idx) .ToArray();// [a,cvec2]=sort(cvec); out_vec_1 = cvec2.Take(nsamp1).Select(v => v > nsamp2).ToArray(); // out_vec_1=cvec2(1:nsamp1)>nsamp2; out_vec_2 = cvec.Take(nsamp2).Select(v => v > nsamp1).ToArray(); // out_vec_2=cvec(1:nsamp2)>nsamp1; //X2 = NaNs(nptsd, 2); // X2=NaN*ones(nptsd,2); //X2.SetSubMatrix(0, nsamp1, 0, X2.Columns, Xk); // X2(1:nsamp1,:)=Xk; //X2 = X2.SortRowsBy(cvec); // X2=X2(cvec,:); X2b = NaNs(nptsd, 2); // X2b=NaN*ones(nptsd,2); X2b.SetSubMatrix(0, nsamp1, 0, X2b.Columns, X); // X2b(1:nsamp1,:)=X; X2b = X2b.SortRowsBy(cvec); // X2b=X2b(cvec,:); Y2 = NaNs(nptsd, 2); // Y2=NaN*ones(nptsd,2); Y2.SetSubMatrix(0, nsamp2, 0, Y2.Columns, Y); // Y2(1:nsamp2,:)=Y; var ind_good = X2b.GetColumn(1).Take(nsamp).FindIdxBy(v => !double.IsNaN(v)); // ind_good=find(~isnan(X2b(1:nsamp,1))); int n_good = ind_good.Length; // n_good=length(ind_good); X3b = X2b.FilterRowsBy(ind_good);// X3b=X2b(ind_good,:); Y3 = Y2.FilterRowsBy(ind_good); // Y3=Y2(ind_good,:); timeused += timer.StopAndSay("计算野点标记向量,重排匹配点"); #endregion #region figure 2 if (display_flag) { //figure(2) //plot(X2(:,1),X2(:,2),'b+',Y2(:,1),Y2(:,2),'ro') //hold on //h=plot([X2(:,1) Y2(:,1)]',[X2(:,2) Y2(:,2)]','k-'); //if display_flag //% set(h,'linewidth',1) //quiver(Xk(:,1),Xk(:,2),cos(tk),sin(tk),0.5,'b') // 画箭头 //quiver(Y(:,1),Y(:,2),cos(t2),sin(t2),0.5,'r') DrawGradient(Xk, Y, tk, t2, N2, N1, String.Format(@"D:\Play Data\Iteration\梯度\{0}.bmp", k), String.Format("Iter={0}梯度方向\n匹配点数{1}", k, n_good)); //end //hold off //axis('ij') //title([int2str(n_good) ' correspondences (warped X)']) //axis([1 N2 1 N1]) //drawnow } #endregion #region figure 3 显示未变形图的匹配关系 if (display_flag) { //% show the correspondences between the untransformed images //figure(3) //plot(X(:,1),X(:,2),'b+',Y(:,1),Y(:,2),'ro') //ind=cvec(ind_good); //hold on //plot([X2b(:,1) Y2(:,1)]',[X2b(:,2) Y2(:,2)]','k-') //hold off //axis('ij') //title([int2str(n_good) ' correspondences (unwarped X)']) //axis([1 N2 1 N1]) //drawnow Draw(X, Y, cvec, null, N2, N1, String.Format(@"D:\Play Data\Iteration\匹配\{0}.bmp", k), String.Format("Iter={0}\n匹配代价{1},匹配数{2}", k, matchcost, n_good)); } #endregion #region 求解变换矩阵 timer.Restart(); Bookstein(X3b, Y3, beta_k, ref cx, ref cy, ref E); // [cx,cy,E]=bookstein(X3b,Y3,beta_k); timeused += timer.StopAndSay("求解变换矩阵"); #endregion #region 通过解出来的变换对点和梯度进行变换 timer.Restart(); // % calculate affine cost var A = MatrixUtils.RankHorizon( cx.GetSubMatrix(n_good + 1, 2, 0, 1), cy.GetSubMatrix(n_good + 1, 2, 0, 1) );//A=[cx(n_good+2:n_good+3,:) cy(n_good+2:n_good+3,:)]; var s = new Svd(A, true).S(); // s=svd(A); aff_cost = Math.Log(s[0] / s[1]); // aff_cost=log(s(1)/s(2)); // % calculate shape context cost min1 = costmat.GetColumns().Select(col => { int minwhere = 0; for (int i = 1; i < col.Count; ++i) { if (col[i] < col[minwhere]) minwhere = i; } return new { Val = col[minwhere], Idx = minwhere }; }).ToArray();// [a1,b1]=min(costmat,[],1); min2 = costmat.GetRows().Select(row => { int minwhere = 0; for (int i = 1; i < row.Count; ++i) { if (row[i] < row[minwhere]) minwhere = i; } return new { Val = row[minwhere], Idx = minwhere }; }).ToArray(); // [a2,b2]=min(costmat,[],2);} sc_cost = Math.Max(min1.Average(a => a.Val), min2.Average(a => a.Val)); // sc_cost=max(mean(a1),mean(a2)); // % warp each coordinate axt = cx.GetSubMatrix(n_good, 3, 0, 1).Transpose(); // axt是cx中的最后三个,即a的x分量 wxt = cx.GetSubMatrix(0, n_good, 0, 1).Transpose(); // wxt是cs中的前n个,即w的x分量 ayt = cy.GetSubMatrix(n_good, 3, 0, 1).Transpose(); wyt = cy.GetSubMatrix(0, n_good, 0, 1).Transpose(); d2 = Dist2(X3b, X).Each(v => v > 0 ? v : 0); // d2=max(dist2(X3b,X),0); U = d2.PointMultiply(d2.Each(v => Math.Log(v + Epsilon))); // U=d2.*log(d2+eps); Debug("MatchCost:{0:F4}\taff_cost:{1:F4}\tsc_cost:{2:F4}\tE:{3:F8}", matchcost, aff_cost, sc_cost, E); var Z = Transformation(X, U, axt, wxt, ayt, wyt); //% apply the warp to the tangent vectors to get the new angles var Xtan = X + tan_eps * MatrixUtils.RankHorizon(t1.Each(Math.Cos), t1.Each(Math.Sin)); // Xtan=X+tan_eps*[cos(t1) sin(t1)]; d2 = Dist2(X3b, Xtan).Each(v => v > 0 ? v : 0); // d2=max(dist2(X3b,Xtan),0); U = d2.PointMultiply(d2.Each(v => Math.Log(v + Epsilon))); // U=d2.*log(d2+eps); //Transformation(Xtan, U, axt, wxt, ayt, wyt, out fx, out fy); //var Ztan = MatrixUtils.RankVertical(fx, fy).Transpose(); // Ztan=[fx; fy]'; var Ztan = Transformation(Xtan, U, axt, wxt, ayt, wyt); for (int i = 0; i < nsamp; ++i) { tk[i, 0] = Math.Atan2(Ztan[i, 1] - Z[i, 1], Ztan[i, 0] - Z[i, 0]); }//tk=atan2(Ztan(:,2)-Z(:,2),Ztan(:,1)-Z(:,1)); timeused += timer.StopAndSay("通过解出来的变换对点和梯度进行变换"); #endregion #region figure 4 显示变形后的点集 if (display_flag) { //figure(4) //plot(Z(:,1),Z(:,2),'b+',Y(:,1),Y(:,2),'ro'); //axis('ij') //title(['k=' int2str(k) ', \lambda_o=' num2str(lambda_o) ', I_f=' num2str(E) ', aff.cost=' num2str(aff_cost) ', SC cost=' num2str(sc_cost)]) //axis([1 N2 1 N1]) //% show warped coordinate grid //fx_aff=cx(n_good+1:n_good+3)'*[ones(1,M); x'; y']; //d2=dist2(X3b,[x y]); //fx_wrp=cx(1:n_good)'*(d2.*log(d2+eps)); //fx=fx_aff+fx_wrp; //fy_aff=cy(n_good+1:n_good+3)'*[ones(1,M); x'; y']; //fy_wrp=cy(1:n_good)'*(d2.*log(d2+eps)); //fy=fy_aff+fy_wrp; //hold on //plot(fx,fy,'k.','markersize',1) //hold off //drawnow d2 = Dist2(X3b, MatrixUtils.RankHorizon(coordX, coordY));//d2=dist2(X3b,[x y]); U = d2.PointMultiply(d2.Each(v => Math.Log(v + Epsilon))); //Transformation(MatrixUtils.RankHorizon(coordX, coordY), U, axt, wxt, ayt, wyt, out fx, out fy); //var coordsT = MatrixUtils.RankVertical(fx, fy).Transpose(); var coordsT = Transformation(MatrixUtils.RankHorizon(coordX, coordY), U, axt, wxt, ayt, wyt); Draw(Z, Y, null, coordsT, N2, N1, String.Format(@"D:\Play Data\Iteration\变换\{0}.bmp", k), String.Format("Iter={0}\nλo={1:F4},If={2:F4},aff_cost{3:F4},sc_cost{4:F4}", k, lambda_o, E, aff_cost, sc_cost)); } #endregion Xk = Z.Clone(); ++k; } #endregion #region 迭代完成后的代价计算 #region 我来尝试计算Dsc // Xk是Q变换后的结果,而Y是模板图形P /* * Dsc = Avg_each_p_in_P(argmin(q in Q, C(p, T(q))) + Avg_each_q_in_Q(argmin(p in P, C(p, T(q))) * */ double mean_dist_final_1; var scQ = ComputeSC(Xk.Transpose(), Zeros(1, nsamp), mean_dist_global, out mean_dist_final_1, out_vec_1); //var scQ = ComputeSC(Xk.Transpose(), Zeros(1, nsamp), mean_dist_1, out mean_dist_final_1, out_vec_1); //var scQ = ComputeSC(Xk.Transpose(), t1.Transpose(), mean_dist_1, out mean_dist_final_1, out_vec_1); double mean_dist_final_2; var scP = ComputeSC(Y.Transpose(), Zeros(1, nsamp), mean_dist_global, out mean_dist_final_2, out_vec_2); //var scP = ComputeSC(Y.Transpose(), Zeros(1, nsamp), mean_dist_2, out mean_dist_final_2, out_vec_2); //var scP = ComputeSC(Y.Transpose(), t2.Transpose(), mean_dist_2, out mean_dist_final_2, out_vec_2); var costmat_final = HistCost(scQ, scP); double distance_sc = costmat_final.GetRows().Select(row => row.Min()).Average() + costmat_final.GetColumns().Select(col => col.Min()).Average(); Debug("distance_sc:{0}", distance_sc); #endregion #region 图像变换和插值 timer.Restart(); //[x,y]=meshgrid(1:N2,1:N1); //x=x(:);y=y(:); Matrix x = null, y = null; MatrixUtils.CreateGrid(N1, N2, out x, out y); //int M = N1 * N2; // M=length(x); d2 = Dist2(X3b, MatrixUtils.RankHorizon(x, y));//d2=dist2(X3b,[x y]); U = d2.PointMultiply(d2.Each(v => Math.Log(v + Epsilon))); //Transformation(MatrixUtils.RankHorizon(x, y), U, axt, wxt, ayt, wyt, out fx, out fy); var fxy = Transformation(MatrixUtils.RankHorizon(x, y), U, axt, wxt, ayt, wyt); //disp('computing warped image...') //V1w=griddata(reshape(fx,N1,N2),reshape(fy,N1,N2),V1,reshape(x,N1,N2),reshape(y,N1,N2)); Matrix V1w = Interpolation( fxy.GetSubMatrix(0, fxy.Rows, 0, 1).Reshape(N1, N2), fxy.GetSubMatrix(0, fxy.Rows, 1, 1).Reshape(N1, N2), V1 ); #region 这个山寨插值方法会造成图像裂缝,用闭运算来尝试修补 Image<Gray, Byte> img = new Image<Gray, byte>(N2, N1); for (int i = 0; i < N2; ++i) { for (int j = 0; j < N1; ++j) { img[i, j] = new Gray(V1w[i, j] * 255); } } var see = new StructuringElementEx(new int[,] { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } }, 1, 1); //img = img.MorphologyEx(see, Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_CLOSE, 1); img = img.Dilate(1).Erode(1); for (int i = 0; i < N2; ++i) { for (int j = 0; j < N1; ++j) { V1w[i, j] = img[i, j].Intensity / 255; } } img.Dispose(); #endregion timeused += timer.StopAndSay("图像变换和插值"); #endregion //fz=find(isnan(V1w)); //V1w(fz)=0; var ssd = (V2 - V1w).Each(v => v * v);//ssd=(V2-V1w).^2; %%%%%%SSD在这里 var ssd_global = ssd.SumAll();//ssd_global=sum(ssd(:)); Debug("ssd_global:{0}", ssd_global); #region figure 5 if (display_flag) { // figure(5) // subplot(2,2,1) // im(V1) // subplot(2,2,2) // im(V2) // subplot(2,2,4) // im(V1w) // title('V1 after warping') // subplot(2,2,3) // im(V2-V1w) // h=title(['SSD=' num2str(ssd_global)]); // colormap(cmap) } #endregion #region 窗口SSD比较 timer.Restart(); //%%% //%%% windowed SSD comparison //%%% var wd = 2 * w + 1;//wd=2*w+1; var win_fun = MatrixUtils.GaussianKernal(wd); //win_fun=gaussker(wd); //% extract sets of blocks around each coordinate //% first do 1st shape; need to use transformed coords. var win_list_1 = Zeros(nsamp, wd * wd);//win_list_1=zeros(nsamp,wd^2); for (int qq = 0; qq < nsamp; ++qq) { int row_qq = (int)Xk[qq, 1],// row_qq=round(Xk(qq,2)); col_qq = (int)Xk[qq, 0];// col_qq=round(Xk(qq,1)); row_qq = Math.Max(w + 1, Math.Min(N1 - w - 1, row_qq));// row_qq=max(w+1,min(N1-w,row_qq)); col_qq = Math.Max(w + 1, Math.Min(N2 - w - 1, col_qq));// col_qq=max(w+1,min(N2-w,col_qq)); // tmp=V1w(row_qq-w:row_qq+w,col_qq-w:col_qq+w); var tmp = V1w.GetSubMatrix(row_qq - w, w * 2 + 1, col_qq - w, w * 2 + 1); tmp = win_fun.PointMultiply(tmp);// tmp=win_fun.*tmp; // win_list_1(qq,:)=tmp(:)'; win_list_1.SetSubMatrix(qq, 1, 0, win_list_1.Columns, tmp.Reshape(1, tmp.Rows * tmp.Columns)); } //% now do 2nd shape var win_list_2 = Zeros(nsamp, wd * wd);//win_list_2=zeros(nsamp,wd^2); for (int qq = 0; qq < nsamp; ++qq) { int row_qq = (int)Y[qq, 1],// row_qq = round(Y(qq, 2)); col_qq = (int)Y[qq, 0];// col_qq = round(Y(qq, 1)); row_qq = Math.Max(w + 1, Math.Min(N1 - w - 1, row_qq));// row_qq=max(w+1,min(N1-w,row_qq)); col_qq = Math.Max(w + 1, Math.Min(N2 - w - 1, col_qq));// col_qq=max(w+1,min(N2-w,col_qq)); // tmp=V2(row_qq-w:row_qq+w,col_qq-w:col_qq+w) var tmp = V2.GetSubMatrix(row_qq - w, w * 2 + 1, col_qq - w, w * 2 + 1); tmp = win_fun.PointMultiply(tmp);// tmp=win_fun.*tmp; win_list_2.SetSubMatrix(qq, 1, 0, win_list_2.Columns, tmp.Reshape(1, tmp.Rows * tmp.Columns));// win_list_2(qq,:)=tmp(:)'; } var ssd_all = Dist2(win_list_1, win_list_2).Each(Math.Sqrt);//ssd_all=sqrt(dist2(win_list_1,win_list_2)); timeused += timer.StopAndSay("窗口SSD比较"); #endregion #region 最后的KNN,不知道干嘛用 timer.Restart(); //%%%%%%% KNN在此 //% loop over nearest neighbors in both directions, project in //% both directions, take maximum double cost_1 = 0, cost_2 = 0; //List<double> cost_1 = new List<double>(), cost_2 = new List<double>(); for (int qq = 0; qq < nsamp; ++qq) { cost_1 += ssd_all[qq, min2[qq].Idx];// cost_1=cost_1+ssd_all(qq,b2(qq)); cost_2 += ssd_all[min1[qq].Idx, qq];// cost_2=cost_2+ssd_all(b1(qq),qq); //cost_1.Add(ssd_all[qq, min2[qq].Idx]); //cost_2.Add(ssd_all[min1[qq].Idx, qq]); } var ssd_local = (1.0 / nsamp) * Math.Max(cost_1, cost_2); var ssd_local_avg = (1.0 / nsamp) * 0.5 * (cost_1 + cost_2); //var ssd_local = (1.0 / nsamp) * Math.Max(cost_1.Average(), cost_2.Average());//ssd_local=(1/nsamp)*max(mean(cost_1),mean(cost_2)); //var ssd_local_avg = (1.0 / nsamp) * 0.5 * (cost_1.Average() + cost_2.Average());//ssd_local_avg=(1/nsamp)*0.5*(mean(cost_1)+mean(cost_2)); Debug("ssd_local:{0}", ssd_local); Debug("ssd_local_avg:{0}", ssd_local_avg); timeused += timer.StopAndSay("计算ssd_local"); #region 最后的组合图 //if display_flag //% set(h,'string',['local SSD=' num2str(ssd_local) ', avg. local SSD=' num2str(ssd_local_avg)]) // set(h,'string',['local SSD=' num2str(ssd_local)]) //end if (display_flag) { Draw(V1, @"D:\Play Data\Iteration\结果\0-V1.bmp", "V1"); Draw(V2, @"D:\Play Data\Iteration\结果\1-V2.bmp", "V2"); Draw(V1w, @"D:\Play Data\Iteration\结果\2-V1w.bmp", "V1 after warping"); Draw(V2 - V1w, @"D:\Play Data\Iteration\结果\3-V2-V1w.bmp", String.Format("local SSD={0:F8}", ssd_local_avg)); } #endregion #endregion #endregion var distance = 1.6 * ssd_local_avg + distance_sc + 0.3 * E; // 不知道最后的距离公式到底是什么 Debug("distance={0:F8}", distance); return distance; }
public void Run() { double totaltime = 0; int s = 100, r = 5; string[] templatefiles = Directory.GetFiles(@"D:\Play Data\train_data\sc\", "*.sc") .Take(100).ToArray(); #region 打开模板 string templatepath = @"D:\Play Data\template\"; int templatecount = templatefiles.Length; Debug("打开{0}个模板--------------------------------------------", templatecount); double[][,] templates = new double[templatecount][, ]; int[] templatenums = new int[templatecount]; timer.Restart(); for (int i = 0; i < templatefiles.Length; ++i) { string file = templatefiles[i]; string filename = Path.GetFileNameWithoutExtension(file); templatenums[i] = int.Parse(filename.Split('-')[1]); templates[i] = new double[s, 60]; using (var fs = new FileStream(file, FileMode.Open)) { using (var br = new BinaryReader(fs)) { for (int j = 0; j < s; ++j) { for (int k = 0; k < 60; ++k) { templates[i][j, k] = br.ReadDouble(); } } } } if (i % 100 == 0) { Debug("已完成{0}个", i); } } Debug("模板读取完成,用时{0}ms.", timer.Stop()); #endregion string[] testfiles = Directory.GetFiles(@"D:\Play Data\test\", "*.bmp") .Take(1000).ToArray(); #region 测试 int testcase = testfiles.Length, acc = 0; Debug("为{0}个对象寻找候选模板------------------------------------------", testcase); foreach (var file in testfiles) { timer.Restart(); string filenameext = Path.GetFileName(file); string filename = Path.GetFileNameWithoutExtension(file); int thisnum = int.Parse(filename.Split('-')[1]); Image <Gray, Byte> img = new Image <Gray, byte>(file); var list = getEdge(img.Resize(2.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR)).Sample(s); var sc100 = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC(list); double[,] scq = new double[r, 60]; for (int i = 0; i < 5; ++i) { int pos = rand.Next(s); for (int k = 0; k < 60; ++k) { scq[i, k] = sc100[pos, k]; } } var arr = new ValueIndexPair <double> [templatecount]; for (int i = 0; i < templatecount; ++i) { double[,] sci = templates[i]; double[,] costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(scq, sci); double cost = 0; for (int j = 0; j < 5; ++j) { double min = double.MaxValue; for (int u = 0; u < s; ++u) { double val = costmat[j, u]; if (val < min) { min = val; } } cost += min; } arr[i] = new ValueIndexPair <double> { Value = cost, Index = i }; } Array.Sort(arr, (a, b) => a.Value.CompareTo(b.Value)); int knn = 10; #region 进行精细匹配 var kmresults = new List <ValueIndexPair <double> >(); foreach (var pair in arr.Take(knn)) { int idx = pair.Index; var costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(templates[idx], sc100); var costmat_int = new int[s, s]; for (int ii = 0; ii < s; ++ii) { for (int jj = 0; jj < s; ++jj) { costmat_int[ii, jj] = (int)(costmat[ii, jj] * 10000); } } var km = new KM(s, costmat_int); km.Match(false); kmresults.Add(new ValueIndexPair <double> { Index = idx, Value = km.MatchResult / 10000.0 }); } kmresults.Sort((a, b) => a.Value.CompareTo(b.Value)); #endregion //int firstmatch = match[0].Num; int firstmatch = templatenums[kmresults[0].Index]; var fc = Console.ForegroundColor; Console.ForegroundColor = firstmatch == thisnum ? ConsoleColor.Green : ConsoleColor.Red; var timeused = timer.Stop(); totaltime += timeused; string info = String.Format("{0} {1}ms\t", filename, timeused); //foreach (var m in bestmatches.Take(4)) { foreach (var m in kmresults.Take(4)) { info += String.Format("{0}/{1:F2}\t", templatenums[m.Index], m.Value); } //Debug(info); if (firstmatch != thisnum) { Console.Write("."); } Console.ForegroundColor = fc; if (firstmatch == thisnum) { ++acc; } } Debug("\nRSC and KM 测试用例:{0}。正确率{1}。", testcase, acc); Console.WriteLine("总用时:{0}ms,平均用时:{1}ms。", totaltime, totaltime / testcase); #endregion }
public override void Draw(SpriteBatch spriteBatch) { spriteBatch.Draw(BG, Vector2.Zero, Color.White); // Draw mouse onHover button if (mhAbout) { spriteBatch.Draw(AboutH, new Vector2(1047, 366), Color.White); } if (mhExit) { spriteBatch.Draw(ExitH, new Vector2(475, 574), Color.White); } if (mhOption) { spriteBatch.Draw(OptionH, new Vector2(98, 362), Color.White); } if (mhRanking) { spriteBatch.Draw(RankingH, new Vector2(986, 57), Color.White); } if (mhStart) { spriteBatch.Draw(StartH, new Vector2(551, 332), Color.White); } // Draw UI when is NOT MainMenu if (!mainScreen) { spriteBatch.Draw(Black, Vector2.Zero, new Color(255, 255, 255, 210)); if (mhBack) { spriteBatch.Draw(back, new Vector2(1230 - back.Width, 50), Color.OrangeRed); } else { spriteBatch.Draw(back, new Vector2(1230 - back.Width, 50), Color.White); } // Draw Option Screen if (showOption) { fontSize = KM.MeasureString("Option"); spriteBatch.DrawString(KM, "Option", new Vector2(Singleton.Instance.Diemensions.X / 2 - fontSize.X / 2, 125), Color.White); spriteBatch.DrawString(Arcanista, "BGM Volume", new Vector2(300, 250), Color.White); spriteBatch.Draw(Arrow, new Vector2(700, 240), null, Color.White, 0, Vector2.Zero, 1f, SpriteEffects.FlipHorizontally, 0f); spriteBatch.DrawString(Arcanista, MasterBGM.ToString(), new Vector2(800, 250), Color.White); spriteBatch.Draw(Arrow, new Vector2(900, 240), Color.White); spriteBatch.DrawString(Arcanista, "SFX Volume", new Vector2(300, 325), Color.White); spriteBatch.Draw(Arrow, new Vector2(700, 315), null, Color.White, 0, Vector2.Zero, 1f, SpriteEffects.FlipHorizontally, 0f); spriteBatch.DrawString(Arcanista, MasterSFX.ToString(), new Vector2(800, 325), Color.White); spriteBatch.Draw(Arrow, new Vector2(900, 315), Color.White); spriteBatch.DrawString(Arcanista, "Full Screen", new Vector2(300, 425), Color.White); if (!FullScreen) { spriteBatch.Draw(checkBoxNo, new Vector2(800, 425), Color.White); } else { spriteBatch.Draw(checkBoxYes, new Vector2(800, 425), Color.White); } spriteBatch.DrawString(Arcanista, "Show FPS", new Vector2(300, 500), Color.White); if (!ShowFPS) { spriteBatch.Draw(checkBoxNo, new Vector2(800, 500), Color.White); } else { spriteBatch.Draw(checkBoxYes, new Vector2(800, 500), Color.White); } if (mhApply) { spriteBatch.Draw(apply, new Vector2(1100 - back.Width, 625), Color.OrangeRed); } else { spriteBatch.Draw(apply, new Vector2(1100 - back.Width, 625), Color.White); } } // Draw About Screen if (showAbout) { fontSize = KM.MeasureString("About"); spriteBatch.DrawString(KM, "About", new Vector2(Singleton.Instance.Diemensions.X / 2 - fontSize.X / 2, 125), Color.White); spriteBatch.DrawString(Arcanista, "Graphics", new Vector2(200, 250), Color.NavajoWhite); spriteBatch.DrawString(Arcanista, "- We create", new Vector2(160, 350), Color.White); spriteBatch.DrawString(Arcanista, "All Graphics", new Vector2(150, 425), Color.White); spriteBatch.DrawString(Arcanista, "Audios", new Vector2(600, 250), Color.NavajoWhite); spriteBatch.DrawString(Arcanista, "- www.sonniss.com", new Vector2(520, 350), Color.White); spriteBatch.DrawString(Arcanista, "Free Audios Bundle", new Vector2(510, 425), Color.White); spriteBatch.DrawString(Arcanista, "Fonts", new Vector2(1000, 250), Color.NavajoWhite); spriteBatch.DrawString(Arcanista, "- Arial", new Vector2(985, 350), Color.White); spriteBatch.DrawString(Arcanista, "- Arcanista", new Vector2(950, 425), Color.White); spriteBatch.DrawString(Arcanista, "- KH-Metropolis", new Vector2(920, 500), Color.White); spriteBatch.DrawString(Arial, "FPS Counter Script : https://stackoverflow.com/questions/20676185", new Vector2(50, 630), Color.White); spriteBatch.DrawString(Arial, "/xna-monogame-getting-the-frames-per-second", new Vector2(350, 660), Color.White); } // Draw Leader board Screen if (showRanking) { fontSize = KM.MeasureString("Ranking"); spriteBatch.DrawString(KM, "Ranking", new Vector2(Singleton.Instance.Diemensions.X / 2 - fontSize.X / 2, 125), Color.White); if (Singleton.Instance.BestTime != null) { fontSize = Arcanista.MeasureString("Best Time : " + Singleton.Instance.BestTime); spriteBatch.DrawString(Arcanista, "Best Time : " + Singleton.Instance.BestTime, new Vector2(Singleton.Instance.Diemensions.X / 2 - fontSize.X / 2, 350), Color.White); fontSize = Arcanista.MeasureString("Best Score : " + Singleton.Instance.BestScore); spriteBatch.DrawString(Arcanista, "Best Score : " + Singleton.Instance.BestScore, new Vector2(Singleton.Instance.Diemensions.X / 2 - fontSize.X / 2, 425), Color.White); } else { fontSize = Arcanista.MeasureString("No Infomation"); spriteBatch.DrawString(Arcanista, "No Infomation", new Vector2(Singleton.Instance.Diemensions.X / 2 - fontSize.X / 2, 350), Color.White); } } } // Draw fade out if (!fadeFinish) { spriteBatch.Draw(Black, Vector2.Zero, _Color); } }
public void Run() { double totaltime = 0; int s = 100, r = 5; string[] templatefiles = Directory.GetFiles(@"D:\Play Data\train_data\sc\", "*.sc") .Take(100).ToArray(); #region 打开模板 string templatepath = @"D:\Play Data\template\"; int templatecount = templatefiles.Length; Debug("打开{0}个模板--------------------------------------------", templatecount); double[][,] templates = new double[templatecount][,]; int[] templatenums = new int[templatecount]; timer.Restart(); for (int i = 0; i < templatefiles.Length; ++i) { string file = templatefiles[i]; string filename = Path.GetFileNameWithoutExtension(file); templatenums[i] = int.Parse(filename.Split('-')[1]); templates[i] = new double[s, 60]; using (var fs = new FileStream(file, FileMode.Open)) { using (var br = new BinaryReader(fs)) { for (int j = 0; j < s; ++j) { for (int k = 0; k < 60; ++k) { templates[i][j, k] = br.ReadDouble(); } } } } if (i % 100 == 0) Debug("已完成{0}个", i); } Debug("模板读取完成,用时{0}ms.", timer.Stop()); #endregion string[] testfiles = Directory.GetFiles(@"D:\Play Data\test\", "*.bmp") .Take(1000).ToArray(); #region 测试 int testcase = testfiles.Length, acc = 0; Debug("为{0}个对象寻找候选模板------------------------------------------", testcase); foreach (var file in testfiles) { timer.Restart(); string filenameext = Path.GetFileName(file); string filename = Path.GetFileNameWithoutExtension(file); int thisnum = int.Parse(filename.Split('-')[1]); Image<Gray, Byte> img = new Image<Gray, byte>(file); var list = getEdge(img.Resize(2.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR)).Sample(s); var sc100 = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC(list); double[,] scq = new double[r, 60]; for (int i = 0; i < 5; ++i) { int pos = rand.Next(s); for (int k = 0; k < 60; ++k) { scq[i, k] = sc100[pos, k]; } } var arr = new ValueIndexPair<double>[templatecount]; for (int i = 0; i < templatecount; ++i) { double[,] sci = templates[i]; double[,] costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(scq, sci); double cost = 0; for (int j = 0; j < 5; ++j) { double min = double.MaxValue; for (int u = 0; u < s; ++u) { double val = costmat[j, u]; if (val < min) min = val; } cost += min; } arr[i] = new ValueIndexPair<double> { Value = cost, Index = i }; } Array.Sort(arr, (a, b) => a.Value.CompareTo(b.Value)); int knn = 10; #region 进行精细匹配 var kmresults = new List<ValueIndexPair<double>>(); foreach (var pair in arr.Take(knn)) { int idx = pair.Index; var costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(templates[idx], sc100); var costmat_int = new int[s, s]; for (int ii = 0; ii < s; ++ii) { for (int jj = 0; jj < s; ++jj) { costmat_int[ii, jj] = (int)(costmat[ii, jj] * 10000); } } var km = new KM(s, costmat_int); km.Match(false); kmresults.Add(new ValueIndexPair<double> { Index = idx, Value = km.MatchResult / 10000.0 }); } kmresults.Sort((a, b) => a.Value.CompareTo(b.Value)); #endregion //int firstmatch = match[0].Num; int firstmatch = templatenums[kmresults[0].Index]; var fc = Console.ForegroundColor; Console.ForegroundColor = firstmatch == thisnum ? ConsoleColor.Green : ConsoleColor.Red; var timeused = timer.Stop(); totaltime += timeused; string info = String.Format("{0} {1}ms\t", filename, timeused); //foreach (var m in bestmatches.Take(4)) { foreach (var m in kmresults.Take(4)) { info += String.Format("{0}/{1:F2}\t", templatenums[m.Index], m.Value); } //Debug(info); if (firstmatch != thisnum) Console.Write("."); Console.ForegroundColor = fc; if (firstmatch == thisnum) { ++acc; } } Debug("\nRSC and KM 测试用例:{0}。正确率{1}。", testcase, acc); Console.WriteLine("总用时:{0}ms,平均用时:{1}ms。", totaltime, totaltime / testcase); #endregion }
public void Run() { double totaltime = 0; int s = 100, r = 5; string[] templatefiles = Directory.GetFiles(@"D:\Play Data\train_data\sc\", "*.sc") .Take(100).ToArray(); #region 打开模板 string templatepath = @"D:\Play Data\template\"; int templatecount = templatefiles.Length; Debug("打开{0}个模板--------------------------------------------", templatecount); double[][,] templates = new double[templatecount][, ]; int[] templatenums = new int[templatecount]; timer.Restart(); for (int i = 0; i < templatefiles.Length; ++i) { string file = templatefiles[i]; string filename = Path.GetFileNameWithoutExtension(file); templatenums[i] = int.Parse(filename.Split('-')[1]); templates[i] = new double[s, 60]; using (var fs = new FileStream(file, FileMode.Open)) { using (var br = new BinaryReader(fs)) { for (int j = 0; j < s; ++j) { for (int k = 0; k < 60; ++k) { templates[i][j, k] = br.ReadDouble(); } } } } if (i % 100 == 0) { Debug("已完成{0}个", i); } } Debug("模板读取完成,用时{0}ms.", timer.Stop()); #endregion string[] testfiles = Directory.GetFiles(@"D:\Play Data\test\", "*.bmp") .Take(100).ToArray(); #region 测试 int testcase = testfiles.Length, acc = 0; Debug("为{0}个对象寻找候选模板------------------------------------------", testcase); foreach (var file in testfiles) { timer.Restart(); string filenameext = Path.GetFileName(file); string filename = Path.GetFileNameWithoutExtension(file); int thisnum = int.Parse(filename.Split('-')[1]); Image <Gray, Byte> img = new Image <Gray, byte>(file); var list = getEdge(img.Resize(2.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR)).Sample(s); var scq = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC(list); var arr = new ValueIndexPair <double> [templatecount]; for (int i = 0; i < templatecount; ++i) { double[,] sci = templates[i]; double[,] costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(scq, sci); var costmat_int = new int[s, s]; for (int ii = 0; ii < s; ++ii) { for (int jj = 0; jj < s; ++jj) { costmat_int[ii, jj] = (int)(costmat[ii, jj] * 10000); } } var km = new KM(s, costmat_int); km.Match(false); arr[i] = new ValueIndexPair <double> { Index = i, Value = km.MatchResult / 10000.0 }; } Array.Sort(arr, (a, b) => a.Value.CompareTo(b.Value)); int[] matchcount = new int[10]; double[] matchcost = new double[10]; int knn = 10; foreach (var pair in arr.Take(knn)) { int num = templatenums[pair.Index]; matchcount[num]++; matchcost[num] += pair.Value; } var match = matchcount.Select((val, i) => new { Count = val, Num = i }) .Where(v => v.Count > 0) .OrderByDescending(v => v.Count).ToArray(); //var match = matchcost.Select((val, i) => new { Cost = val / matchcount[i], Num = i }) // .Where(v => !double.IsNaN(v.Cost)) // .OrderBy(v => v.Cost).ToArray(); #region 进行精细匹配,效果一般 //double[] matchrate = new double[10]; //foreach (var m in match) { // if (m.Count == 0) break; // string template = Path.Combine(templatepath, m.Num + ".bmp"); // Jim.OCR.ShapeContext2D.ShapeContext sc = new Jim.OCR.ShapeContext2D.ShapeContext(file, template); // sc.debug_flag = false; // sc.timer_flag = false; // sc.display_flag = false; // sc.n_iter = 3; // sc.matchScale = 2.5; // sc.maxsamplecount = 100; // matchrate[m.Num] = sc.MatchFile(); //} //var bestmatches = matchrate.Select((val, i) => new { Cost = val, Num = i }) // .Where(m => m.Cost > 0) // .OrderBy(m => m.Cost).ToArray(); //int firstmatch = bestmatches[0].Num; #endregion int firstmatch = match[0].Num; var fc = Console.ForegroundColor; Console.ForegroundColor = firstmatch == thisnum ? ConsoleColor.Green : ConsoleColor.Red; var timeused = timer.Stop(); totaltime += timeused; string info = String.Format("{0} {1}ms - {2}\t", filename, timeused, (firstmatch == thisnum ? "Right" : "Wrong")); //foreach (var m in bestmatches.Take(4)) { foreach (var m in match) { info += String.Format("{0}/{1}\t", m.Num, m.Count); //info += String.Format("{0}/{1:F3}\t", m.Num, m.Cost); //info += String.Format("{0}/{1:F3}\t", m.Num, m.Cost); } Debug(info); Console.ForegroundColor = fc; if (firstmatch == thisnum) { ++acc; } } Debug("测试用例:{0}。正确率{1}。", testcase, acc); Console.WriteLine("总用时:{0}ms,平均用时:{1}ms。", totaltime, totaltime / testcase); #endregion }
public KM Match() { KM km = new KM(scsa.Length + scsb.Length, cost); km.Match(false); return km; }
private static void testMNIST() { var timer = new MyTimer(); List<Point>[] Edges = new List<Point>[10]; #region 准备边缘集合 //Font standardFont = new Font("Arial", 20); //for (int i = 0; i < 10; ++i) { // Image<Bgr, Byte> img = new Image<Bgr, byte>(28, 28); // using (Graphics g = Graphics.FromImage(img.Bitmap)) { // g.Clear(Color.Black); // g.DrawString(i.ToString(), standardFont, Brushes.White, 0, 0); // } // Edges[i] = getEdge(img.Convert<Gray, Byte>()); // //img.Save(Path.Combine(@"D:\Play Data\", i + ".bmp")); //} for (int i = 0; i < 10; ++i) { string template = Path.Combine(@"D:\Play Data\template", i + ".bmp"); Image<Gray, Byte> img = new Image<Gray, byte>(template); Edges[i] = getEdge(img); } #endregion List<string> wrong = new List<string>(); int testcount = 100, pos = 0; foreach (var file in Directory.GetFiles(@"D:\Play Data\test", "*.bmp")) { if (pos == testcount) break; string filename = Path.GetFileNameWithoutExtension(file); int ans = int.Parse(filename.Split('-')[1]); timer.Restart(); List<Point> edge = getEdge(new Image<Gray, byte>(file)); ImageShapeContext[] isc1 = new ImageShapeContext[10]; ImageShapeContext[] isc2 = new ImageShapeContext[10]; KM[] kms = new KM[10]; double[] results = new double[10]; int scale = 8; for (int d = 0; d < 10; ++d) { int samplecount = Math.Min(edge.Count, Edges[d].Count); var sc = createISC(edge, samplecount); var sci = createISC(Edges[d], samplecount); var scm = new ShapeContextMatching(sc.ShapeContests, sci.ShapeContests); scm.BuildCostGraph(); var km = scm.Match(); isc1[d] = sc; isc2[d] = sci; kms[d] = km; results[d] = (double)km.MatchResult / samplecount; } var sort = results.Select((c, i) => new { Cost = c, Digit = i }).OrderBy(v => v.Cost).ToArray(); if (sort[0].Digit == ans) { var fc = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Green; string s = String.Format("File:{0}-{1}ms-Right!\t", filename, timer.Stop()); for (int i = 0; i < 4; ++i) { s += String.Format("{0}/{1:F4}, ", sort[i].Digit, sort[i].Cost); } Debug(s); Console.ForegroundColor = fc; } else { var fc = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; wrong.Add(filename); string s = String.Format("File:{0}-{1}ms-Wrong!", filename, timer.Stop()); for (int i = 0; i < 5; ++i) { s += String.Format("{0}/{1:F2}, ", sort[i].Digit, sort[i].Cost); } Debug(s); Console.ForegroundColor = fc; string dir = Path.Combine(@"D:\Play Data\output", filename); if (Directory.Exists(dir)) Directory.Delete(dir, true); Directory.CreateDirectory(dir); for (int d = 0; d < 10; ++d) { var sc = isc1[d]; var sci = isc2[d]; var km = kms[d]; int ax = (int)sc.Points.Average(p => p.X), ay = (int)sc.Points.Average(p => p.Y), bx = (int)sci.Points.Average(p => p.X), by = (int)sci.Points.Average(p => p.Y); int dx = bx - ax, dy = by - ay; Image<Bgr, Byte> img = new Image<Bgr, byte>(28 * scale, 28 * scale); Font fs = new Font("Arial", 18); using (Graphics g = Graphics.FromImage(img.Bitmap)) { g.Clear(Color.Black); for (int j = 0; j < sci.Points.Count; ++j) { int i = km.MatchPair[j + sc.Points.Count]; Point pb = sci.Points[j], pa = sc.Points[i]; pb.X -= dx; pb.Y -= dy; int r = 2; g.DrawEllipse(Pens.Red, pa.X * scale - r, pa.Y * scale - r, r * 2 + 1, r * 2 + 1); g.DrawEllipse(Pens.Green, pb.X * scale - r, pb.Y * scale - r, r * 2 + 1, r * 2 + 1); g.DrawLine(Pens.Gray, new Point(pa.X * scale, pa.Y * scale), new Point(pb.X * scale, pb.Y * scale)); } g.DrawString(results[d].ToString(), fs, Brushes.White, new PointF(0, 0)); } img.Save(Path.Combine(dir, d + ".bmp")); } } ++pos; } Debug("Wrong:{0}", wrong.Count); Debug("Wrong rate:{0:F2}%", 100.0 * wrong.Count / testcount); }
public void Run() { double totaltime = 0; int s = 100, r = 5; string[] templatefiles = Directory.GetFiles(@"D:\Play Data\train_data\sc\", "*.sc") .Take(100).ToArray(); #region 打开模板 string templatepath = @"D:\Play Data\template\"; int templatecount = templatefiles.Length; Debug("打开{0}个模板--------------------------------------------", templatecount); double[][,] templates = new double[templatecount][,]; int[] templatenums = new int[templatecount]; timer.Restart(); for (int i = 0; i < templatefiles.Length; ++i) { string file = templatefiles[i]; string filename = Path.GetFileNameWithoutExtension(file); templatenums[i] = int.Parse(filename.Split('-')[1]); templates[i] = new double[s, 60]; using (var fs = new FileStream(file, FileMode.Open)) { using (var br = new BinaryReader(fs)) { for (int j = 0; j < s; ++j) { for (int k = 0; k < 60; ++k) { templates[i][j, k] = br.ReadDouble(); } } } } if (i % 100 == 0) Debug("已完成{0}个", i); } Debug("模板读取完成,用时{0}ms.", timer.Stop()); #endregion string[] testfiles = Directory.GetFiles(@"D:\Play Data\test\", "*.bmp") .Take(100).ToArray(); #region 测试 int testcase = testfiles.Length, acc = 0; Debug("为{0}个对象寻找候选模板------------------------------------------", testcase); foreach (var file in testfiles) { timer.Restart(); string filenameext = Path.GetFileName(file); string filename = Path.GetFileNameWithoutExtension(file); int thisnum = int.Parse(filename.Split('-')[1]); Image<Gray, Byte> img = new Image<Gray, byte>(file); var list = getEdge(img.Resize(2.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR)).Sample(s); var scq = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC(list); var arr = new ValueIndexPair<double>[templatecount]; for (int i = 0; i < templatecount; ++i) { double[,] sci = templates[i]; double[,] costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(scq, sci); var costmat_int = new int[s, s]; for (int ii = 0; ii < s; ++ii) { for (int jj = 0; jj < s; ++jj) { costmat_int[ii, jj] = (int)(costmat[ii, jj] * 10000); } } var km = new KM(s, costmat_int); km.Match(false); arr[i] = new ValueIndexPair<double> { Index = i, Value = km.MatchResult / 10000.0 }; } Array.Sort(arr, (a, b) => a.Value.CompareTo(b.Value)); int[] matchcount = new int[10]; double[] matchcost = new double[10]; int knn = 10; foreach (var pair in arr.Take(knn)) { int num = templatenums[pair.Index]; matchcount[num]++; matchcost[num] += pair.Value; } var match = matchcount.Select((val, i) => new { Count = val, Num = i }) .Where(v => v.Count > 0) .OrderByDescending(v => v.Count).ToArray(); //var match = matchcost.Select((val, i) => new { Cost = val / matchcount[i], Num = i }) // .Where(v => !double.IsNaN(v.Cost)) // .OrderBy(v => v.Cost).ToArray(); #region 进行精细匹配,效果一般 //double[] matchrate = new double[10]; //foreach (var m in match) { // if (m.Count == 0) break; // string template = Path.Combine(templatepath, m.Num + ".bmp"); // Jim.OCR.ShapeContext2D.ShapeContext sc = new Jim.OCR.ShapeContext2D.ShapeContext(file, template); // sc.debug_flag = false; // sc.timer_flag = false; // sc.display_flag = false; // sc.n_iter = 3; // sc.matchScale = 2.5; // sc.maxsamplecount = 100; // matchrate[m.Num] = sc.MatchFile(); //} //var bestmatches = matchrate.Select((val, i) => new { Cost = val, Num = i }) // .Where(m => m.Cost > 0) // .OrderBy(m => m.Cost).ToArray(); //int firstmatch = bestmatches[0].Num; #endregion int firstmatch = match[0].Num; var fc = Console.ForegroundColor; Console.ForegroundColor = firstmatch == thisnum ? ConsoleColor.Green : ConsoleColor.Red; var timeused = timer.Stop(); totaltime += timeused; string info = String.Format("{0} {1}ms - {2}\t", filename, timeused, (firstmatch == thisnum ? "Right" : "Wrong")); //foreach (var m in bestmatches.Take(4)) { foreach (var m in match) { info += String.Format("{0}/{1}\t", m.Num, m.Count); //info += String.Format("{0}/{1:F3}\t", m.Num, m.Cost); //info += String.Format("{0}/{1:F3}\t", m.Num, m.Cost); } Debug(info); Console.ForegroundColor = fc; if (firstmatch == thisnum) { ++acc; } } Debug("测试用例:{0}。正确率{1}。", testcase, acc); Console.WriteLine("总用时:{0}ms,平均用时:{1}ms。", totaltime, totaltime / testcase); #endregion }
public double MatchIteration(Matrix X, Matrix Y, Matrix V1, Matrix V2, Matrix t1, Matrix t2) { timer.Clear(); double timeused = 0; timer.Restart(); var tk = t1.Clone(); // tk=t1; int w = 4; int ndum = (int)(nsamp * ndum_frac); nsamp1 = nsamp2 = nsamp; #region demo2迭代 Matrix Xk = X.Clone(); int N1 = V1.Rows, N2 = V2.Columns; if (display_flag) { Draw(X, Y, V1, V2, @"D:\Play Data\Iteration\原图.bmp", "原始图像和采样"); //DrawGradient(X, Y, t1, t2, N2, N1, @"D:\Play Data\Iteration\原图梯度.bmp", "原始图像切向量"); } int k = 0; var out_vec_1 = Utils.InitArray <bool>(nsamp1, false); //out_vec_1=zeros(1,nsamp1); var out_vec_2 = Utils.InitArray <bool>(nsamp2, false); //out_vec_2=zeros(1,nsamp2); double ori_weight = 0.1; double tan_eps = 1.0; bool affine_start_flag = true; bool polarity_flag = true; double matchcost = double.MaxValue; double sc_cost = 0, aff_cost = 0, E = 0; Matrix cx = null, cy = null; // cx, cy是插值线性方程组的解的两列 Matrix axt = null, wxt = null, ayt = null, wyt = null, d2 = null, U = null, X2 = null, Y2 = null, X2b = null, X3b = null, Y3 = null; double mean_dist_1 = 0, mean_dist_2 = 0; var min1 = new[] { new { Val = 0.0, Idx = 0 } }; var min2 = min1; #region 用于打网格的坐标 Matrix coordX = null, coordY = null; int coordMargin = (int)(N1 * coordMarginRate); MatrixUtils.CreateGrid(N1 + coordMargin * 2, N2 + coordMargin * 2, out coordX, out coordY); coordX = coordX.Each(v => v - coordMargin * 2); coordY = coordY.Each(v => v - coordMargin * 2); //int MM = N1 * N2 / 25; // M=length(x); #endregion timeused += timer.StopAndSay("初始化"); while (k < n_iter) { Debug("Iter={0}", k); #region 计算两个形状上下文 timer.Restart(); // [BH1,mean_dist_1]=sc_compute(Xk',zeros(1,nsamp),mean_dist_global,nbins_theta,nbins_r,r_inner,r_outer,out_vec_1); var BH1 = ComputeSC(Xk.Transpose(), Zeros(1, nsamp), mean_dist_global, out mean_dist_1, out_vec_1); //var BH1 = ComputeSC(Xk.Transpose(), t1.Transpose(), mean_dist_global, out mean_dist_1, out_vec_1); // [BH2,mean_dist_2]=sc_compute(Y',zeros(1,nsamp),mean_dist_global,nbins_theta,nbins_r,r_inner,r_outer,out_vec_2); var BH2 = ComputeSC(Y.Transpose(), Zeros(1, nsamp), mean_dist_global, out mean_dist_2, out_vec_2); //var BH2 = ComputeSC(Y.Transpose(), t2.Transpose(), mean_dist_global, out mean_dist_2, out_vec_2); timeused += timer.StopAndSay("计算两个形状上下文"); Debug("Mean_dist_1:{0:F4}", mean_dist_1); Debug("Mean_dist_2:{0:F4}", mean_dist_2); #endregion #region 计算lambda_o和beta_k double lambda_o; if (affine_start_flag) { if (k == 0) { lambda_o = 1000; } else { lambda_o = beta_init * Math.Pow(r, k - 1); // lambda_o=beta_init*r^(k-2); } } else { lambda_o = beta_init * Math.Pow(r, k); // lambda_o=beta_init*r^(k-1); } double beta_k = mean_dist_2 * mean_dist_2 * lambda_o; #endregion #region 计算代价矩阵 timer.Restart(); var costmat_shape = HistCost(BH1, BH2); // costmat_shape = hist_cost_2(BH1, BH2); // theta_diff=repmat(tk,1,nsamp)-repmat(t2',nsamp,1); var theta_diff = tk.RepMat(1, nsamp) - t2.Transpose().RepMat(nsamp, 1); Matrix costmat_theta; if (polarity_flag) { // costmat_theta=0.5*(1-cos(theta_diff)); //costmat_theta = 0.5 * (Ones(costmat_shape.Rows, costmat_shape.Columns) - theta_diff.Each(v => Math.Cos(v))); costmat_theta = theta_diff.Each(v => 0.5 * (1 - Math.Cos(v))); } else { // costmat_theta=0.5*(1-cos(2*theta_diff)); //costmat_theta = 0.5 * (Ones(costmat_shape.Rows, costmat_shape.Columns) - theta_diff.Each(v => Math.Cos(2 * v))); costmat_theta = theta_diff.Each(v => 0.5 * (1 - Math.Cos(2 * v))); } // costmat=(1-ori_weight)*costmat_shape+ori_weight*costmat_theta; var costmat = (1 - ori_weight) * costmat_shape + ori_weight * costmat_theta; int nptsd = nsamp + ndum; // nptsd=nsamp+ndum; var costmat2 = new DenseMatrix(nptsd, nptsd, eps_dum); // costmat2=eps_dum*ones(nptsd,nptsd); costmat2.SetSubMatrix(0, nsamp, 0, nsamp, costmat); // costmat2(1:nsamp,1:nsamp)=costmat; timeused += timer.StopAndSay("计算代价矩阵"); #endregion #region 匈牙利算法 timer.Restart(); var costmat_int = new int[nptsd, nptsd]; for (int i = 0; i < nptsd; ++i) { for (int j = 0; j < nptsd; ++j) { costmat_int[i, j] = (int)(costmat2[i, j] * 10000); } } var km = new KM(nptsd, costmat_int); km.Match(false); matchcost = km.MatchResult / 10000.0; int[] cvec = km.MatchPair; // cvec=hungarian(costmat2); timeused += timer.StopAndSay("匈牙利算法"); #endregion #region 计算野点标记向量,重排匹配点 timer.Restart(); int[] cvec2 = cvec.Select((v, i) => new { Val = v, Idx = i }) .OrderBy(v => v.Val) .Select(v => v.Idx) .ToArray(); // [a,cvec2]=sort(cvec); out_vec_1 = cvec2.Take(nsamp1).Select(v => v > nsamp2).ToArray(); // out_vec_1=cvec2(1:nsamp1)>nsamp2; out_vec_2 = cvec.Take(nsamp2).Select(v => v > nsamp1).ToArray(); // out_vec_2=cvec(1:nsamp2)>nsamp1; //X2 = NaNs(nptsd, 2); // X2=NaN*ones(nptsd,2); //X2.SetSubMatrix(0, nsamp1, 0, X2.Columns, Xk); // X2(1:nsamp1,:)=Xk; //X2 = X2.SortRowsBy(cvec); // X2=X2(cvec,:); X2b = NaNs(nptsd, 2); // X2b=NaN*ones(nptsd,2); X2b.SetSubMatrix(0, nsamp1, 0, X2b.Columns, X); // X2b(1:nsamp1,:)=X; X2b = X2b.SortRowsBy(cvec); // X2b=X2b(cvec,:); Y2 = NaNs(nptsd, 2); // Y2=NaN*ones(nptsd,2); Y2.SetSubMatrix(0, nsamp2, 0, Y2.Columns, Y); // Y2(1:nsamp2,:)=Y; var ind_good = X2b.GetColumn(1).Take(nsamp).FindIdxBy(v => !double.IsNaN(v)); // ind_good=find(~isnan(X2b(1:nsamp,1))); int n_good = ind_good.Length; // n_good=length(ind_good); X3b = X2b.FilterRowsBy(ind_good); // X3b=X2b(ind_good,:); Y3 = Y2.FilterRowsBy(ind_good); // Y3=Y2(ind_good,:); timeused += timer.StopAndSay("计算野点标记向量,重排匹配点"); #endregion #region figure 2 if (display_flag) { //figure(2) //plot(X2(:,1),X2(:,2),'b+',Y2(:,1),Y2(:,2),'ro') //hold on //h=plot([X2(:,1) Y2(:,1)]',[X2(:,2) Y2(:,2)]','k-'); //if display_flag //% set(h,'linewidth',1) //quiver(Xk(:,1),Xk(:,2),cos(tk),sin(tk),0.5,'b') // 画箭头 //quiver(Y(:,1),Y(:,2),cos(t2),sin(t2),0.5,'r') DrawGradient(Xk, Y, tk, t2, N2, N1, String.Format(@"D:\Play Data\Iteration\梯度\{0}.bmp", k), String.Format("Iter={0}梯度方向\n匹配点数{1}", k, n_good)); //end //hold off //axis('ij') //title([int2str(n_good) ' correspondences (warped X)']) //axis([1 N2 1 N1]) //drawnow } #endregion #region figure 3 显示未变形图的匹配关系 if (display_flag) { //% show the correspondences between the untransformed images //figure(3) //plot(X(:,1),X(:,2),'b+',Y(:,1),Y(:,2),'ro') //ind=cvec(ind_good); //hold on //plot([X2b(:,1) Y2(:,1)]',[X2b(:,2) Y2(:,2)]','k-') //hold off //axis('ij') //title([int2str(n_good) ' correspondences (unwarped X)']) //axis([1 N2 1 N1]) //drawnow Draw(X, Y, cvec, null, N2, N1, String.Format(@"D:\Play Data\Iteration\匹配\{0}.bmp", k), String.Format("Iter={0}\n匹配代价{1},匹配数{2}", k, matchcost, n_good)); } #endregion #region 求解变换矩阵 timer.Restart(); Bookstein(X3b, Y3, beta_k, ref cx, ref cy, ref E); // [cx,cy,E]=bookstein(X3b,Y3,beta_k); timeused += timer.StopAndSay("求解变换矩阵"); #endregion #region 通过解出来的变换对点和梯度进行变换 timer.Restart(); // % calculate affine cost var A = MatrixUtils.RankHorizon( cx.GetSubMatrix(n_good + 1, 2, 0, 1), cy.GetSubMatrix(n_good + 1, 2, 0, 1) ); //A=[cx(n_good+2:n_good+3,:) cy(n_good+2:n_good+3,:)]; var s = new Svd(A, true).S(); // s=svd(A); aff_cost = Math.Log(s[0] / s[1]); // aff_cost=log(s(1)/s(2)); // % calculate shape context cost min1 = costmat.GetColumns().Select(col => { int minwhere = 0; for (int i = 1; i < col.Count; ++i) { if (col[i] < col[minwhere]) { minwhere = i; } } return(new { Val = col[minwhere], Idx = minwhere }); }).ToArray();// [a1,b1]=min(costmat,[],1); min2 = costmat.GetRows().Select(row => { int minwhere = 0; for (int i = 1; i < row.Count; ++i) { if (row[i] < row[minwhere]) { minwhere = i; } } return(new { Val = row[minwhere], Idx = minwhere }); }).ToArray(); // [a2,b2]=min(costmat,[],2);} sc_cost = Math.Max(min1.Average(a => a.Val), min2.Average(a => a.Val)); // sc_cost=max(mean(a1),mean(a2)); // % warp each coordinate axt = cx.GetSubMatrix(n_good, 3, 0, 1).Transpose(); // axt是cx中的最后三个,即a的x分量 wxt = cx.GetSubMatrix(0, n_good, 0, 1).Transpose(); // wxt是cs中的前n个,即w的x分量 ayt = cy.GetSubMatrix(n_good, 3, 0, 1).Transpose(); wyt = cy.GetSubMatrix(0, n_good, 0, 1).Transpose(); d2 = Dist2(X3b, X).Each(v => v > 0 ? v : 0); // d2=max(dist2(X3b,X),0); U = d2.PointMultiply(d2.Each(v => Math.Log(v + Epsilon))); // U=d2.*log(d2+eps); Debug("MatchCost:{0:F4}\taff_cost:{1:F4}\tsc_cost:{2:F4}\tE:{3:F8}", matchcost, aff_cost, sc_cost, E); var Z = Transformation(X, U, axt, wxt, ayt, wyt); //% apply the warp to the tangent vectors to get the new angles var Xtan = X + tan_eps * MatrixUtils.RankHorizon(t1.Each(Math.Cos), t1.Each(Math.Sin)); // Xtan=X+tan_eps*[cos(t1) sin(t1)]; d2 = Dist2(X3b, Xtan).Each(v => v > 0 ? v : 0); // d2=max(dist2(X3b,Xtan),0); U = d2.PointMultiply(d2.Each(v => Math.Log(v + Epsilon))); // U=d2.*log(d2+eps); //Transformation(Xtan, U, axt, wxt, ayt, wyt, out fx, out fy); //var Ztan = MatrixUtils.RankVertical(fx, fy).Transpose(); // Ztan=[fx; fy]'; var Ztan = Transformation(Xtan, U, axt, wxt, ayt, wyt); for (int i = 0; i < nsamp; ++i) { tk[i, 0] = Math.Atan2(Ztan[i, 1] - Z[i, 1], Ztan[i, 0] - Z[i, 0]); }//tk=atan2(Ztan(:,2)-Z(:,2),Ztan(:,1)-Z(:,1)); timeused += timer.StopAndSay("通过解出来的变换对点和梯度进行变换"); #endregion #region figure 4 显示变形后的点集 if (display_flag) { //figure(4) //plot(Z(:,1),Z(:,2),'b+',Y(:,1),Y(:,2),'ro'); //axis('ij') //title(['k=' int2str(k) ', \lambda_o=' num2str(lambda_o) ', I_f=' num2str(E) ', aff.cost=' num2str(aff_cost) ', SC cost=' num2str(sc_cost)]) //axis([1 N2 1 N1]) //% show warped coordinate grid //fx_aff=cx(n_good+1:n_good+3)'*[ones(1,M); x'; y']; //d2=dist2(X3b,[x y]); //fx_wrp=cx(1:n_good)'*(d2.*log(d2+eps)); //fx=fx_aff+fx_wrp; //fy_aff=cy(n_good+1:n_good+3)'*[ones(1,M); x'; y']; //fy_wrp=cy(1:n_good)'*(d2.*log(d2+eps)); //fy=fy_aff+fy_wrp; //hold on //plot(fx,fy,'k.','markersize',1) //hold off //drawnow d2 = Dist2(X3b, MatrixUtils.RankHorizon(coordX, coordY));//d2=dist2(X3b,[x y]); U = d2.PointMultiply(d2.Each(v => Math.Log(v + Epsilon))); //Transformation(MatrixUtils.RankHorizon(coordX, coordY), U, axt, wxt, ayt, wyt, out fx, out fy); //var coordsT = MatrixUtils.RankVertical(fx, fy).Transpose(); var coordsT = Transformation(MatrixUtils.RankHorizon(coordX, coordY), U, axt, wxt, ayt, wyt); Draw(Z, Y, null, coordsT, N2, N1, String.Format(@"D:\Play Data\Iteration\变换\{0}.bmp", k), String.Format("Iter={0}\nλo={1:F4},If={2:F4},aff_cost{3:F4},sc_cost{4:F4}", k, lambda_o, E, aff_cost, sc_cost)); } #endregion Xk = Z.Clone(); ++k; } #endregion #region 迭代完成后的代价计算 #region 我来尝试计算Dsc // Xk是Q变换后的结果,而Y是模板图形P /* * Dsc = Avg_each_p_in_P(argmin(q in Q, C(p, T(q))) + Avg_each_q_in_Q(argmin(p in P, C(p, T(q))) * */ double mean_dist_final_1; var scQ = ComputeSC(Xk.Transpose(), Zeros(1, nsamp), mean_dist_global, out mean_dist_final_1, out_vec_1); //var scQ = ComputeSC(Xk.Transpose(), Zeros(1, nsamp), mean_dist_1, out mean_dist_final_1, out_vec_1); //var scQ = ComputeSC(Xk.Transpose(), t1.Transpose(), mean_dist_1, out mean_dist_final_1, out_vec_1); double mean_dist_final_2; var scP = ComputeSC(Y.Transpose(), Zeros(1, nsamp), mean_dist_global, out mean_dist_final_2, out_vec_2); //var scP = ComputeSC(Y.Transpose(), Zeros(1, nsamp), mean_dist_2, out mean_dist_final_2, out_vec_2); //var scP = ComputeSC(Y.Transpose(), t2.Transpose(), mean_dist_2, out mean_dist_final_2, out_vec_2); var costmat_final = HistCost(scQ, scP); double distance_sc = costmat_final.GetRows().Select(row => row.Min()).Average() + costmat_final.GetColumns().Select(col => col.Min()).Average(); Debug("distance_sc:{0}", distance_sc); #endregion #region 图像变换和插值 timer.Restart(); //[x,y]=meshgrid(1:N2,1:N1); //x=x(:);y=y(:); Matrix x = null, y = null; MatrixUtils.CreateGrid(N1, N2, out x, out y); //int M = N1 * N2; // M=length(x); d2 = Dist2(X3b, MatrixUtils.RankHorizon(x, y));//d2=dist2(X3b,[x y]); U = d2.PointMultiply(d2.Each(v => Math.Log(v + Epsilon))); //Transformation(MatrixUtils.RankHorizon(x, y), U, axt, wxt, ayt, wyt, out fx, out fy); var fxy = Transformation(MatrixUtils.RankHorizon(x, y), U, axt, wxt, ayt, wyt); //disp('computing warped image...') //V1w=griddata(reshape(fx,N1,N2),reshape(fy,N1,N2),V1,reshape(x,N1,N2),reshape(y,N1,N2)); Matrix V1w = Interpolation( fxy.GetSubMatrix(0, fxy.Rows, 0, 1).Reshape(N1, N2), fxy.GetSubMatrix(0, fxy.Rows, 1, 1).Reshape(N1, N2), V1 ); #region 这个山寨插值方法会造成图像裂缝,用闭运算来尝试修补 Image <Gray, Byte> img = new Image <Gray, byte>(N2, N1); for (int i = 0; i < N2; ++i) { for (int j = 0; j < N1; ++j) { img[i, j] = new Gray(V1w[i, j] * 255); } } var see = new StructuringElementEx(new int[, ] { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } }, 1, 1); //img = img.MorphologyEx(see, Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_CLOSE, 1); img = img.Dilate(1).Erode(1); for (int i = 0; i < N2; ++i) { for (int j = 0; j < N1; ++j) { V1w[i, j] = img[i, j].Intensity / 255; } } img.Dispose(); #endregion timeused += timer.StopAndSay("图像变换和插值"); #endregion //fz=find(isnan(V1w)); //V1w(fz)=0; var ssd = (V2 - V1w).Each(v => v * v); //ssd=(V2-V1w).^2; %%%%%%SSD在这里 var ssd_global = ssd.SumAll(); //ssd_global=sum(ssd(:)); Debug("ssd_global:{0}", ssd_global); #region figure 5 if (display_flag) { // figure(5) // subplot(2,2,1) // im(V1) // subplot(2,2,2) // im(V2) // subplot(2,2,4) // im(V1w) // title('V1 after warping') // subplot(2,2,3) // im(V2-V1w) // h=title(['SSD=' num2str(ssd_global)]); // colormap(cmap) } #endregion #region 窗口SSD比较 timer.Restart(); //%%% //%%% windowed SSD comparison //%%% var wd = 2 * w + 1; //wd=2*w+1; var win_fun = MatrixUtils.GaussianKernal(wd); //win_fun=gaussker(wd); //% extract sets of blocks around each coordinate //% first do 1st shape; need to use transformed coords. var win_list_1 = Zeros(nsamp, wd * wd);//win_list_1=zeros(nsamp,wd^2); for (int qq = 0; qq < nsamp; ++qq) { int row_qq = (int)Xk[qq, 1], // row_qq=round(Xk(qq,2)); col_qq = (int)Xk[qq, 0]; // col_qq=round(Xk(qq,1)); row_qq = Math.Max(w + 1, Math.Min(N1 - w - 1, row_qq)); // row_qq=max(w+1,min(N1-w,row_qq)); col_qq = Math.Max(w + 1, Math.Min(N2 - w - 1, col_qq)); // col_qq=max(w+1,min(N2-w,col_qq)); // tmp=V1w(row_qq-w:row_qq+w,col_qq-w:col_qq+w); var tmp = V1w.GetSubMatrix(row_qq - w, w * 2 + 1, col_qq - w, w * 2 + 1); tmp = win_fun.PointMultiply(tmp);// tmp=win_fun.*tmp; // win_list_1(qq,:)=tmp(:)'; win_list_1.SetSubMatrix(qq, 1, 0, win_list_1.Columns, tmp.Reshape(1, tmp.Rows * tmp.Columns)); } //% now do 2nd shape var win_list_2 = Zeros(nsamp, wd * wd);//win_list_2=zeros(nsamp,wd^2); for (int qq = 0; qq < nsamp; ++qq) { int row_qq = (int)Y[qq, 1], // row_qq = round(Y(qq, 2)); col_qq = (int)Y[qq, 0]; // col_qq = round(Y(qq, 1)); row_qq = Math.Max(w + 1, Math.Min(N1 - w - 1, row_qq)); // row_qq=max(w+1,min(N1-w,row_qq)); col_qq = Math.Max(w + 1, Math.Min(N2 - w - 1, col_qq)); // col_qq=max(w+1,min(N2-w,col_qq)); // tmp=V2(row_qq-w:row_qq+w,col_qq-w:col_qq+w) var tmp = V2.GetSubMatrix(row_qq - w, w * 2 + 1, col_qq - w, w * 2 + 1); tmp = win_fun.PointMultiply(tmp); // tmp=win_fun.*tmp; win_list_2.SetSubMatrix(qq, 1, 0, win_list_2.Columns, tmp.Reshape(1, tmp.Rows * tmp.Columns)); // win_list_2(qq,:)=tmp(:)'; } var ssd_all = Dist2(win_list_1, win_list_2).Each(Math.Sqrt);//ssd_all=sqrt(dist2(win_list_1,win_list_2)); timeused += timer.StopAndSay("窗口SSD比较"); #endregion #region 最后的KNN,不知道干嘛用 timer.Restart(); //%%%%%%% KNN在此 //% loop over nearest neighbors in both directions, project in //% both directions, take maximum double cost_1 = 0, cost_2 = 0; //List<double> cost_1 = new List<double>(), cost_2 = new List<double>(); for (int qq = 0; qq < nsamp; ++qq) { cost_1 += ssd_all[qq, min2[qq].Idx]; // cost_1=cost_1+ssd_all(qq,b2(qq)); cost_2 += ssd_all[min1[qq].Idx, qq]; // cost_2=cost_2+ssd_all(b1(qq),qq); //cost_1.Add(ssd_all[qq, min2[qq].Idx]); //cost_2.Add(ssd_all[min1[qq].Idx, qq]); } var ssd_local = (1.0 / nsamp) * Math.Max(cost_1, cost_2); var ssd_local_avg = (1.0 / nsamp) * 0.5 * (cost_1 + cost_2); //var ssd_local = (1.0 / nsamp) * Math.Max(cost_1.Average(), cost_2.Average());//ssd_local=(1/nsamp)*max(mean(cost_1),mean(cost_2)); //var ssd_local_avg = (1.0 / nsamp) * 0.5 * (cost_1.Average() + cost_2.Average());//ssd_local_avg=(1/nsamp)*0.5*(mean(cost_1)+mean(cost_2)); Debug("ssd_local:{0}", ssd_local); Debug("ssd_local_avg:{0}", ssd_local_avg); timeused += timer.StopAndSay("计算ssd_local"); #region 最后的组合图 //if display_flag //% set(h,'string',['local SSD=' num2str(ssd_local) ', avg. local SSD=' num2str(ssd_local_avg)]) // set(h,'string',['local SSD=' num2str(ssd_local)]) //end if (display_flag) { Draw(V1, @"D:\Play Data\Iteration\结果\0-V1.bmp", "V1"); Draw(V2, @"D:\Play Data\Iteration\结果\1-V2.bmp", "V2"); Draw(V1w, @"D:\Play Data\Iteration\结果\2-V1w.bmp", "V1 after warping"); Draw(V2 - V1w, @"D:\Play Data\Iteration\结果\3-V2-V1w.bmp", String.Format("local SSD={0:F8}", ssd_local_avg)); } #endregion #endregion #endregion var distance = 1.6 * ssd_local_avg + distance_sc + 0.3 * E; // 不知道最后的距离公式到底是什么 Debug("distance={0:F8}", distance); return(distance); }
private static void km() { /* string[] ss = @"3 4 6 4 9 6 4 5 3 8 7 5 3 4 2 6 3 2 2 5 8 4 5 4 7".Split('\n');*/ string[] ss = @"7 6 4 6 1 4 6 5 7 2 3 5 7 6 8 4 7 8 8 5 2 6 5 6 3".Split('\n'); int[,] g = new int[5, 5]; for (int i = 0; i < 5; ++i) { var l = ss[i].Split(' '); for (int j = 0; j < 5; ++j) { g[i, j] = int.Parse(l[j]); } } var km = new KM(5, g); int val = km.Match(false); Console.WriteLine(val); for (int i = 0; i < 5; ++i) { Console.WriteLine("Y{0} -> X{1} @ {2}", i, km.MatchPair[i], g[km.MatchPair[i], i]); } }
/// <summary> /// /// </summary> /// <param name="image"></param> public void UpdateImage(KM.JXC.DBA.Image image) { using (KuanMaiEntities db = new KuanMaiEntities()) { Image imge = (from img in db.Image where img.ID == image.ID select img).FirstOrDefault<Image>(); if (imge == null) { throw new KMJXCException("图片不存在"); } base.UpdateProperties(imge, image); db.SaveChanges(); } }
public void Run() { double totaltime = 0; int s = 100, K = 100, m = 100; string[] templatefiles = Directory.GetFiles(@"D:\Play Data\train_data\scq-" + K + "-" + m, "*.scq") .Take(20000).ToArray(); string[] templateSCfiles = Directory.GetFiles(@"D:\Play Data\train_data\sc\", "*.sc") .Take(20000).ToArray(); #region 打开量化的模板 int templatecount = templatefiles.Length; Debug("打开{0}个量化模板----------------------------------------", templatecount); timer.Restart(); int[][] templatehistograms = new int[templatecount][]; int[] templatenums = new int[templatecount]; for (int f = 0; f < templatecount; ++f) { string file = templatefiles[f]; string filename = Path.GetFileNameWithoutExtension(file); templatenums[f] = int.Parse(filename.Split('-')[1]); templatehistograms[f] = new int[K]; using (var fs = new FileStream(file, FileMode.Open)) { using (var br = new BinaryReader(fs)) { for (int i = 0; i < K; ++i) { templatehistograms[f][i] = br.ReadInt32(); } } } } Debug("打开完成,用时{0}ms.", timer.Stop()); #endregion #region 打开Shapeme Debug("打开{0}个Shapeme.", K); timer.Restart(); double[][] shapemes = new double[K][]; using (var fs = new FileStream(Path.Combine(@"D:\Play Data\train_data\sm-" + K, m + ".sm"), FileMode.Open)) { using (var br = new BinaryReader(fs)) { for (int i = 0; i < K; ++i) { shapemes[i] = new double[60]; for (int k = 0; k < 60; ++k) { shapemes[i][k] = br.ReadDouble(); } } } } Debug("Shapeme读取完成,用时{0}ms.", timer.Stop()); #endregion string[] testfiles = Directory.GetFiles(@"D:\Play Data\test\", "*.bmp") .Take(1000).ToArray(); #region 测试 int testcase = testfiles.Length, acc = 0; Debug("为{0}个对象寻找候选模板------------------------------------------", testcase); foreach (var file in testfiles) { timer.Restart(); #region 计算待测图的形状上下文 string filenameext = Path.GetFileName(file); string filename = Path.GetFileNameWithoutExtension(file); int thisnum = int.Parse(filename.Split('-')[1]); Image <Gray, Byte> img = new Image <Gray, byte>(file); var list = getEdge(img.Resize(2.5, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR)).Sample(s); var sc = Jim.OCR.ShapeContext2D.ShapeContext.ComputeSC2(list); var sc2 = new double[s, 60]; for (int i = 0; i < s; ++i) { for (int j = 0; j < 60; ++j) { sc2[i, j] = sc[i][j]; } } #endregion #region 对待测图的形状上下文进行量化 int[] histogram = new int[K]; for (int i = 0; i < s; ++i) { double[] ds = new double[K]; for (int j = 0; j < K; ++j) { ds[j] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(sc[i], shapemes[j]); } int id = ds.Select((v, idx) => new ValueIndexPair <double> { Value = v, Index = idx }) .OrderBy(p => p.Value) .First().Index; ++histogram[id]; } #endregion #region 计算量化后的比较距离 double[] dists = new double[templatecount]; for (int i = 0; i < templatecount; ++i) { dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.ChiSquareDistance(histogram, templatehistograms[i]); //dists[i] = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(histogram.Cast<double>().ToArray(), templatehistograms[i].Cast<double>().ToArray()); } #endregion #region 对结果进行排序和统计 var arr = dists.Select((d, i) => new ValueIndexPair <double> { Value = d, Index = i }) .OrderBy(p => p.Value); int knn = 10; #endregion #region 进行精细匹配 var kmresults = new List <ValueIndexPair <double> >(); foreach (var pair in arr.Take(knn)) { int idx = pair.Index; var scfile = templateSCfiles[idx]; // var sci = new double[s][]; var sci = new double[s, 60]; using (var fs = new FileStream(scfile, FileMode.Open)) { using (var br = new BinaryReader(fs)) { for (int j = 0; j < s; ++j) { //sci[j] = new double[60]; for (int k = 0; k < 60; ++k) { //sci[j][k] = br.ReadDouble(); sci[j, k] = br.ReadDouble(); } } } } var costmat = Jim.OCR.ShapeContext2D.ShapeContext.HistCost(sci, sc2); var costmat_int = new int[s, s]; for (int ii = 0; ii < s; ++ii) { for (int jj = 0; jj < s; ++jj) { costmat_int[ii, jj] = (int)(costmat[ii, jj] * 10000); } } var km = new KM(s, costmat_int); km.Match(false); kmresults.Add(new ValueIndexPair <double> { Index = idx, Value = km.MatchResult / 10000.0 }); } kmresults.Sort((a, b) => a.Value.CompareTo(b.Value)); #endregion //int firstmatch = match[0].Num; int firstmatch = templatenums[kmresults[0].Index]; var fc = Console.ForegroundColor; Console.ForegroundColor = firstmatch == thisnum ? ConsoleColor.Green : ConsoleColor.Red; var timeused = timer.Stop(); totaltime += timeused; string info = String.Format("{0} {1}ms\t", filename, timeused); //foreach (var m in bestmatches.Take(4)) { foreach (var mmm in kmresults.Take(4)) { info += String.Format("{0}/{1:F2}\t", templatenums[mmm.Index], mmm.Value); } //Debug(info); if (firstmatch != thisnum) { Console.Write("."); } Console.ForegroundColor = fc; if (firstmatch == thisnum) { ++acc; } } Debug("\nShapeme and KM 测试用例:{0}。正确率{1}。", testcase, acc); Console.WriteLine("总用时:{0}ms,平均用时:{1}ms。", totaltime, totaltime / testcase); #endregion }
public static String Pager(KM.JXC.BL.Models.BPageData data) { System.Text.StringBuilder pageHtml = new System.Text.StringBuilder(); long total = data.TotalRecords; long totalPage = 0; int curPage = data.Page; int pageSize = data.PageSize; string url=data.URL; if(url.IndexOf("page=")>-1) { string s = url.Substring(0, url.IndexOf("page=")); if (s.EndsWith("&")) { s = s.Substring(0,s.Length-1); } string e = url.Substring(url.IndexOf("page=")+6); url = s; if (e.IndexOf("&") > -1) { url += e.Substring(e.IndexOf("&")); } } if (url.IndexOf('?') < 0) { url += "?"; } else { if (!url.EndsWith("?")) { url += "&"; } } //No need to page if (total <= pageSize) { return null; } if (total % pageSize == 0) { totalPage = total / pageSize; } else { totalPage = (total / pageSize)+1; } pageHtml.Append("<a class=\"pn\" href=\""+url+"page=1\">首页</a>"); if (curPage > 1) { pageHtml.Append("<a class=\"pn\" href=\"" + url + "page=" + (curPage - 1) + "\">上一页</a>"); } long start = 1; long end = totalPage; if (curPage - 5 > 0) { start = curPage - 5; } if (curPage + 5 <= totalPage) { end = curPage + 5; } for (long i = start; i <= end; i++) { if (curPage != i) { pageHtml.Append("<a class=\"pn\" href=\"" + url + "page=" + i.ToString() + "\">" + i.ToString() + "</a>"); } else { pageHtml.Append("<span class=\"spn\">" + i.ToString() + "</span>"); } } if (curPage < totalPage) { pageHtml.Append("<a class=\"pn\" href=\"" + url + "page=" + (curPage + 1) + "\">下一页</a>"); } pageHtml.Append("<a class=\"pn\" href=\"" + url + "page=" + totalPage.ToString() + "\">末页</a>"); pageHtml.Append("<span>共:</span>"+totalPage+ "页"); return pageHtml.ToString(); }