Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.Util;
namespace new_test
{
class Program
{
public static OpenCvSharp.Point2f ComputeIntersect(OpenCvSharp.Vec4i a, OpenCvSharp.Vec4i b)
{
int x1 = a[0];
int y1 = a[1];
int x2 = a[2];
int y2 = a[3];
int x3 = a[0];
int y3 = a[1];
int x4 = a[2];
int y4 = a[3];
float d = 0;
//int x = 0;
//int y = 0;
//OpenCvSharp.Point2f pt = new OpenCvSharp.Point2f();
if (d == ((float)(x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4)))
{
OpenCvSharp.Point2f pt = new OpenCvSharp.Point2f();
pt.X = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
pt.Y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;
return pt;
}
else
{
OpenCvSharp.Point2f ptt = new OpenCvSharp.Point2f(-1, -1);
return ptt;//OpenCvSharp.Point2f(-1, -1);
}
}
public static bool comparator2(double a, double b)
{
return a < b;
}
public static bool comparator3(OpenCvSharp.Vec3f a, OpenCvSharp.Vec3f b)
{
return a[0] < b[0];
}
public static bool comparator(OpenCvSharp.Point2f a, OpenCvSharp.Point2f b)
{
return a.X < b.X;
}
public static void sortCorners(List<OpenCvSharp.Point2f> corners, OpenCvSharp.Point2f center)
{
List<OpenCvSharp.Point2f> top = new List<OpenCvSharp.Point2f>();
List<OpenCvSharp.Point2f> top_out = new List<OpenCvSharp.Point2f>();
List<OpenCvSharp.Point2f> bot = new List<OpenCvSharp.Point2f>();
List<OpenCvSharp.Point2f> bot_out = new List<OpenCvSharp.Point2f>();
for (int i = 0; i < corners.Count; i++)
{
if (corners[i].Y < center.Y)
{
top.Add(corners[i]);//List<T>.Add()
}
else
{
bot.Add(corners[i]);
}
}
// wala q kasabot ani <<from c++>>
//sort(top.begin(), top.end(), comparator);
//sort(bot.begin(), bot.end(), comparator);
//OpenCvSharp.Cv2.Sort(top.GetEnumerator(), top.Last(), comparator);
//OpenCvSharp.Cv2.Sort(bot.GetEnumerator(), top.Last(), comparator);
//List<OpenCVSharp.Point2f> top_out = new List<OpenCVSharp.Point2f>();
OpenCvSharp.Cv2.Sort(InputArray.Create(top), OutputArray.Create(top_out), SortFlags.EveryColumn);
OpenCvSharp.Cv2.Sort(InputArray.Create(bot), OutputArray.Create(bot_out), SortFlags.EveryColumn);
OpenCvSharp.Point2f tl = top[0];
OpenCvSharp.Point2f tr = top[top.Count() - 1];
OpenCvSharp.Point2f bl = top[0];
OpenCvSharp.Point2f br = top[bot.Count() - 1];
corners.Clear();
corners.Add(tl);
corners.Add(tr);
corners.Add(bl);
corners.Add(br);
}
static void Main(string[] args)
{
OpenCvSharp.Mat img = OpenCvSharp.Cv2.ImRead("D:/Jonathan David/Documents/Visual Studio 2015/Projects/new+test/example.jpg"/*"example.jpg"*/, 0);
OpenCvSharp.Size size = new OpenCvSharp.Size(3, 3);
OpenCvSharp.Cv2.GaussianBlur(img, img, size, 0);
//from c++
//adaptiveThreshold(img, img,255,CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY,75,10);
OpenCvSharp.Cv2.AdaptiveThreshold(img, img, 255, AdaptiveThresholdTypes.MeanC /*CV_ADAPTIVE_THRESH_MEAN C*/, ThresholdTypes.Binary /*CV_THRESH_BINARY*/, 75, 10);
OpenCvSharp.Cv2.BitwiseNot(img, img);
OpenCvSharp.Mat img2 = new OpenCvSharp.Mat();
//from c++ << cvtColor(img, img2, CV_GRAY2RGB);
OpenCvSharp.Cv2.CvtColor(img, img2, ColorConversionCodes.GRAY2RGB/*CV_GRAY2RGB*/);
OpenCvSharp.Mat img3 = new OpenCvSharp.Mat();
//from c++ << cvtColor(img, img3, CV_GRAY2RGB);
OpenCvSharp.Cv2.CvtColor(img, img3, ColorConversionCodes.GRAY2RGB /*CV_GRAY2RGB*/);
List<OpenCvSharp.Vec4i> lines = new List<Vec4i>();
//from c++ << HoughLinesP(img, lines, 1, CV_PI / 180, 80, 400, 10);
OpenCvSharp.Cv2.HoughLines(img, 1, Math.PI / 180, 80, 400, 10);
//from c++ << for( size_t i = 0; i < lines.size(); i++ ) size_t =unassign int
for (int i = 0; i < lines.Count; i++)
{
//converted c# Vec4i l = lines[i]; with error
// int ii = Convert.ToInt32(i);
//OpenCvSharp.Vec4i l = lines[ii];
//from c++ << line(img2, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA);
//converted OpenCvSharp.Cv2.Line(img2, OpenCvSharp.Point(l[0], l[1]), OpenCvSharp.Point(l[2], l[3]), Scalar(0, 0, 255)/*blue*/, 3, CV_AA);
OpenCvSharp.Cv2.Line(img2, 0, 1, 2, 3, Scalar.Blue, 3, LineTypes.AntiAlias);
}
OpenCvSharp.Cv2.ImShow("example", img);
List<OpenCvSharp.Point2f> corners = new List<OpenCvSharp.Point2f>();
for (int i = 0; i < lines.Count; i++)
{
for (int j = i + 1; j < lines.Count; j++)
{
//ORIGINAL LINE: cv::Point2f pt = computeIntersect(lines[i], lines[j]);
//converted << cv.Point2f pt = computeIntersect(new List(lines[i]), new List(lines[j]));
OpenCvSharp.Point pt = ComputeIntersect(lines[i], lines[j]);
if (pt.X >= 0 && pt.Y >= 0 && pt.X < img.Cols && pt.Y < img.Rows)
{
corners.Add(pt);
}
}
}
//Get mass center daw
OpenCvSharp.Point2f center = new OpenCvSharp.Point2f(0, 0);
for (int i = 0; i < corners.Count; i++)
{
center += corners[i];
}
center *= (1.0 / corners.Count);
sortCorners(corners, center);
OpenCvSharp.Rect r = OpenCvSharp.Cv2.BoundingRect(corners);
Console.Write(r);
Console.Write("\n");
//from c++ << cv::Mat quad = cv::Mat::zeros(r.height, r.width, CV_8UC3);
OpenCvSharp.Mat quad = Mat.Zeros(r.Height, r.Width, MatType.CV_8UC3);
//Corners of the destination image
OpenCvSharp.Point2f a = new OpenCvSharp.Point2f(0, 0);
OpenCvSharp.Point2f b = new OpenCvSharp.Point2f(quad.Cols, 0);
OpenCvSharp.Point2f cc = new OpenCvSharp.Point2f(quad.Cols, quad.Rows);
OpenCvSharp.Point2f d = new OpenCvSharp.Point2f(0, quad.Rows);
List<OpenCvSharp.Point2f> quad_pts = new List<OpenCvSharp.Point2f>();
quad_pts.Add(a);//(OpenCvSharp.Point2f(0, 0));
quad_pts.Add(b);//(OpenCvSharp.Point2f(quad.Cols, 0));
quad_pts.Add(cc);//(OpenCvSharp.Point2f(quad.Cols, quad.Rows));
quad_pts.Add(d);//(OpenCvSharp.Point2f(0, quad.Rows));
//quad_pts.ad
//Get transformation matrix
OpenCvSharp.Mat transmtx = OpenCvSharp.Cv2.GetPerspectiveTransform(corners, quad_pts);
//Apply perspective transformation
OpenCvSharp.Cv2.WarpPerspective(img3, quad, transmtx, quad.Size());
OpenCvSharp.Cv2.ImShow("example2", quad);
OpenCvSharp.Mat cimg = new OpenCvSharp.Mat();
OpenCvSharp.Cv2.CvtColor(quad, cimg, ColorConversionCodes.BGR2GRAY);
List<Vec3f> circles = new List<Vec3f>();
// HoughCircles(cimg, circles, CV_HOUGH_GRADIENT, 1, img.rows / 8, 100, 75, 0, 0);
OpenCvSharp.Cv2.HoughCircles(cimg, OpenCvSharp.HoughMethods.Gradient, 1, img.Rows / 8, 100, 75, 0, 0);
for (uint i = 0; i < circles.Count; i++)
{
int ii = Convert.ToInt32(i);
// i change center to centers
//Point center = new Point(cvRound(circles[i][0]), cvRound(circles[i][1]));
//OpenCvSharp.Point centers = new OpenCvSharp.Point(circles[ii][0],circles[ii][1]);//(cvRound(circles[ii][0]), cvRound(circles[ii][1]));
//circle center
//circle(quad, center, 3, Scalar(0, 255, 0), -1, 8, 0);
int cx = Convert.ToInt32(circles[ii][0]);
int cy = Convert.ToInt32(circles[ii][1]);
OpenCvSharp.Cv2.Circle(quad, cx, cy, 3, Scalar.YellowGreen, -1, LineTypes.Link8, 0);
}
OpenCvSharp.Cv2.ImShow("example4", quad);
OpenCvSharp.Cv2.WaitKey();
double averR = 0;
List<double> row = new List<double>();
List<double> row_out = new List<double>();
List<double> col = new List<double>();
List<double> col_out = new List<double>();
//Find rows and columns of circle for interpolation
for (int i = 0; i < circles.Count; i++)
{
bool found = false;
int rc = Convert.ToInt32(circles[i][2]);
averR += rc;
//int x = cvRound(circles[i][0]);
int x = Convert.ToInt32(circles[i][0]);
//int y = cvRound(circles[i][1]);
int y = Convert.ToInt32(circles[i][1]);
for (int j = 0; j < row.Count; j++)
{
double y2 = row[j];
if (y - rc < y2 && y + rc > y2)
{
found = true;
break;
}
}
if (!found)
{
row.Add(y);
}
found = false;
for (int j = 0; j < col.Count; j++)
{
double x2 = col[j];
if (x - rc < x2 && x + rc > x2)
{
found = true;
break;
}
}
if (!found)
{
col.Add(x);
}
}
averR /= circles.Count;
//List<OpenCVSharp.Point2f> top_out = new List<OpenCVSharp.Point2f>();
//OpenCvSharp.Cv2.Sort(InputArray.Create(top), OutputArray.Create(top_out), SortFlags.Ascending);
OpenCvSharp.Cv2.Sort(InputArray.Create(row), OutputArray.Create(row_out), SortFlags.Ascending);
OpenCvSharp.Cv2.Sort(InputArray.Create(col), OutputArray.Create(col_out), SortFlags.Ascending);
for (int i = 0; i < row.Count; i++)
{
double max = 0;
double y = row[i];
int ind = -1;
for (int j = 0; j < col.Count; j++)
{
double x = col[j];
Point c = new Point(x, y);
//Use an actual circle if it exists
for (int k = 0; k < circles.Count; k++)
{
double x2 = circles[k][0];
double y2 = circles[k][1];
if (Math.Abs(y2 - y) < averR && Math.Abs(x2 - x) < averR)
{
x = x2;
y = y2;
}
}
// circle outline
//int aver = Convert.ToInt32(averR);
OpenCvSharp.Cv2.Circle(quad, Convert.ToInt32(x), Convert.ToInt32(y), Convert.ToInt32(averR), Scalar.Blue/* Scalar(0, 0, 255)*/, 3, LineTypes.Link8, 0);
Rect rect = new Rect(Convert.ToInt32(x) - Convert.ToInt32(averR), Convert.ToInt32(y) - Convert.ToInt32(averR), 2 * Convert.ToInt32(averR), 2 * Convert.ToInt32(averR));
//Mat submat = cimg.Clone(rect);//cimg(rect);
Mat submat = cimg.SubMat(rect);
double p = (double)OpenCvSharp.Cv2.CountNonZero(submat) / (submat.Size().Width * submat.Size().Height);
if (p >= 0.3 && p > max)
{
max = p;
ind = j;
}
}
if (ind == -1)
{
Console.Write("{0:D}:-", i + 1);
}
else
{
Console.Write("{0:D}:{1}", i + 1, 'A' + ind);
}
Console.Write("\n");
}
// circle outline*/
OpenCvSharp.Cv2.ImShow("example3", quad);
OpenCvSharp.Cv2.WaitKey();
}
}
}