public myPicture doSmooth(myPicture input, matrix mat)
        {
            Bitmap ret = new Bitmap(input.width, input.height);

            int r = mat.n / 2, s = mat.m / 2;

            for (int i = 0; i < input.width; ++i)
            {
                for (int j = 0; j < input.height; ++j)
                {
                    double tmp = 0;
                    for (int p = -r; p <= r; ++p)
                    {
                        for (int q = -s; q <= s; ++q)
                        {
                            tmp += 1.0 * input.getGrayDegree(i - p, j - q) * mat.a[p + r, q + s];
                        }
                    }
                    int val = (int)tmp;
                    if (val < 0)
                    {
                        val = 0;
                    }
                    if (val > 255)
                    {
                        val = 255;
                    }
                    ret.SetPixel(i, j, Color.FromArgb(val, val, val));
                }
            }

            return(new myPicture(ret, input.path));
        }
        public myPicture doSharp(myPicture input)
        {
            Bitmap ret = new Bitmap(input.width, input.height);

            for (int i = 0; i < input.width; ++i)
            {
                for (int j = 0; j < input.height; ++j)
                {
                    int dx = (input.getGrayDegree(i - 1, j - 1) + 2 * input.getGrayDegree(i - 1, j) + input.getGrayDegree(i - 1, j + 1)) - (input.getGrayDegree(i + 1, j - 1) + 2 * input.getGrayDegree(i + 1, j) + input.getGrayDegree(i + 1, j + 1));
                    int dy = (input.getGrayDegree(i - 1, j + 1) + 2 * input.getGrayDegree(i, j + 1) + input.getGrayDegree(i + 1, j + 1)) - (input.getGrayDegree(i - 1, j - 1) + 2 * input.getGrayDegree(i, j - 1) + input.getGrayDegree(i + 1, j - 1));
                    if (dx < 0)
                    {
                        dx = -dx;
                    }
                    if (dy < 0)
                    {
                        dy = -dy;
                    }
                    int d = Math.Max(dx, dy);
                    if (d > 255)
                    {
                        d = 255;
                    }
                    ret.SetPixel(i, j, Color.FromArgb(d, d, d));
                }
            }
            return(new myPicture(ret, input.path));
        }
Beispiel #3
0
        //输入:原图
        public getDigits(myPicture input)
        {
            int width  = input.width;
            int height = input.height;
            //生成图片
            Bitmap pic = new Bitmap(width, height);

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    int cur = input.grayDegree[i, j];
                    pic.SetPixel(i, j, Color.FromArgb(cur, cur, cur));
                }
            }

            //获取文件路径和文件格式
            int len = input.path.Length, pos = -1;

            for (int i = len - 1; i >= 0; i--)
            {
                if (input.path[i] == '.')
                {
                    pos = i;
                }
            }
            if (pos != -1)
            {
                filePath = input.path.Substring(0, pos) + "_gray.bmp";
            }
            else
            {
                filePath = input.path + ".bmp";
            }
            System.Drawing.Imaging.ImageFormat imgformat = System.Drawing.Imaging.ImageFormat.Bmp;
            //保存图片
            pic.Save(filePath, imgformat);

            //调用第三方软件
            Process myPro = new Process();

            myPro.StartInfo.FileName               = "cmd.exe";
            myPro.StartInfo.UseShellExecute        = false;
            myPro.StartInfo.RedirectStandardInput  = true;
            myPro.StartInfo.RedirectStandardOutput = true;
            myPro.StartInfo.RedirectStandardError  = true;
            myPro.StartInfo.CreateNoWindow         = true;
            myPro.Start();
            textPath = filePath.Substring(0, filePath.Length - 4);
            string str = "tesseract " + filePath + " " + textPath + " digits";

            myPro.StandardInput.WriteLine(str);
            myPro.StandardInput.AutoFlush = true;
            myPro.Close();
        }
        //输入:锐化和二值化后的图像,输出:找到的最大连通块,即最外层圆
        public myPicture init(myPicture input)
        {
            width  = input.width;
            height = input.height;
            gray   = new int[width, height];
            vis    = new int[width, height];
            //获取灰度值
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    gray[i, j] = input.picture.GetPixel(i, j).B;
                    vis[i, j]  = 0;
                }
            }

            //找到最大连通块
            int cou = 0, no = 1, ans = 0;

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    if (vis[i, j] == 0 && gray[i, j] == 255)
                    {
                        cnt = 0;
                        dfs(i, j, no);
                        if (cou < cnt)
                        {
                            cou = cnt;
                            ans = no;
                        }
                        no++;
                    }
                }
            }
            //将最大连通块变为白色,其他区域变为黑色
            Bitmap res = new Bitmap(width, height);

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    if (vis[i, j] == ans)
                    {
                        res.SetPixel(i, j, Color.FromArgb(255, 255, 255));
                    }
                    else
                    {
                        res.SetPixel(i, j, Color.FromArgb(0, 0, 0));
                    }
                }
            }
            return(new myPicture(res));
        }
        //输入:原图和圆心信息(圆心位置和半径),输出:直线所在区域(包含较少噪声的圆环)
        public myPicture doFind(myPicture input, circle cir)
        {
            int    width = input.width, height = input.height;
            Bitmap res = new Bitmap(width, height);
            int    x = (int)cir.x, y = (int)cir.y;
            //截取圆环为0.15*半径——0.5*半径
            int maxr = (int)(0.5 * cir.r), minr = (int)(0.15 * cir.r);

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    res.SetPixel(i, j, Color.FromArgb(255, 255, 255));
                }
            }
            //将0.15*半径——0.5*半径区域赋值成原图像内容
            for (int i = -maxr; i <= maxr; i++)
            {
                int pos1 = -1;
                for (int j = 0; j < height; j++)
                {
                    if (i * i + j * j <= maxr * maxr)
                    {
                        pos1 = j;
                        break;
                    }
                }
                int pos2 = -1;
                for (int j = height - 1; j >= 0; j--)
                {
                    if (i * i + j * j <= maxr * maxr)
                    {
                        pos2 = j;
                        break;
                    }
                }
                if (pos1 == -1)
                {
                    continue;
                }
                for (int j = pos1; j <= pos2; j++)
                {
                    if (i * i + j * j < minr * minr)
                    {
                        continue;
                    }
                    res.SetPixel(x + i, y + j, input.picture.GetPixel(x + i, y + j));
                    res.SetPixel(x + i, y - j, input.picture.GetPixel(x + i, y - j));
                }
            }
            return(new myPicture(res));
        }
Beispiel #6
0
        public myPicture doSmooth(myPicture input)
        {
            Bitmap ret = new Bitmap(input.width, input.height);

            for (int i = 2; i + 2 < input.width; ++i)
            {
                for (int j = 2; j + 2 < input.height; ++j)
                {
                    List <int> part0 = new List <int> {
                        input.grayDegree[i - 1, j - 2], input.grayDegree[i, j - 2], input.grayDegree[i + 1, j - 2], input.grayDegree[i - 1, j - 1], input.grayDegree[i, j - 1], input.grayDegree[i + 1, j - 1], input.grayDegree[i, j]
                    };
                    List <int> part1 = new List <int> {
                        input.grayDegree[i - 1, j + 2], input.grayDegree[i, j + 2], input.grayDegree[i + 1, j + 2], input.grayDegree[i - 1, j + 1], input.grayDegree[i, j + 1], input.grayDegree[i + 1, j + 1], input.grayDegree[i, j]
                    };
                    List <int> part2 = new List <int> {
                        input.grayDegree[i - 2, j - 1], input.grayDegree[i - 2, j], input.grayDegree[i - 2, j + 1], input.grayDegree[i - 1, j - 1], input.grayDegree[i - 1, j], input.grayDegree[i - 1, j + 1], input.grayDegree[i, j]
                    };
                    List <int> part3 = new List <int> {
                        input.grayDegree[i + 2, j - 1], input.grayDegree[i + 2, j], input.grayDegree[i + 2, j + 1], input.grayDegree[i + 1, j - 1], input.grayDegree[i + 1, j], input.grayDegree[i + 1, j + 1], input.grayDegree[i, j]
                    };
                    List <int> part4 = new List <int> {
                        input.grayDegree[i - 2, j - 2], input.grayDegree[i - 2, j - 1], input.grayDegree[i - 1, j - 2], input.grayDegree[i - 1, j - 1], input.grayDegree[i - 1, j], input.grayDegree[i, j - 1], input.grayDegree[i, j]
                    };
                    List <int> part5 = new List <int> {
                        input.grayDegree[i + 2, j - 2], input.grayDegree[i + 2, j - 1], input.grayDegree[i + 1, j - 2], input.grayDegree[i + 1, j - 1], input.grayDegree[i + 1, j], input.grayDegree[i, j - 1], input.grayDegree[i, j]
                    };
                    List <int> part6 = new List <int> {
                        input.grayDegree[i + 2, j + 2], input.grayDegree[i + 2, j + 1], input.grayDegree[i + 1, j + 2], input.grayDegree[i + 1, j + 1], input.grayDegree[i + 1, j], input.grayDegree[i, j + 1], input.grayDegree[i, j]
                    };
                    List <int> part7 = new List <int> {
                        input.grayDegree[i - 2, j + 2], input.grayDegree[i - 2, j + 1], input.grayDegree[i - 1, j + 2], input.grayDegree[i - 1, j + 1], input.grayDegree[i - 1, j], input.grayDegree[i, j + 1], input.grayDegree[i, j]
                    };
                    List <int> part8 = new List <int> {
                        input.grayDegree[i - 1, j - 1], input.grayDegree[i - 1, j], input.grayDegree[i - 1, j + 1], input.grayDegree[i, j - 1], input.grayDegree[i, j], input.grayDegree[i, j + 1], input.grayDegree[i + 1, j - 1], input.grayDegree[i + 1, j], input.grayDegree[i + 1, j + 1]
                    };
                    List <square> tmp = new List <square>();
                    tmp.Add(new square(part0));
                    tmp.Add(new square(part1));
                    tmp.Add(new square(part2));
                    tmp.Add(new square(part3));
                    tmp.Add(new square(part4));
                    tmp.Add(new square(part5));
                    tmp.Add(new square(part6));
                    tmp.Add(new square(part7));
                    tmp.Add(new square(part8));
                    tmp.Sort(new squareCmp());
                    int val = (int)tmp[0].average;
                    ret.SetPixel(i, j, Color.FromArgb(val, val, val));
                }
            }
            return(new myPicture(ret, input.path));
        }
Beispiel #7
0
        public myPicture doSharp(myPicture input)
        {
            matrix mat = new matrix(3, 3);

            mat.a[0, 1] = -1;
            mat.a[1, 0] = -1;
            mat.a[1, 1] = 4;
            mat.a[1, 2] = -1;
            mat.a[2, 1] = -1;
            smoothTemplate smooth = new smoothTemplate();

            return(smooth.doSmooth(input, mat));
        }
Beispiel #8
0
        public myPicture to01Pic()
        {
            myPicture ret = this;

            for (int i = 0; i < width; ++i)
            {
                for (int j = 0; j < height; ++j)
                {
                    int val = grayDegree[i, j];
                    ret.picture.SetPixel(i, j, Color.FromArgb(val, val, val));
                }
            }
            return(ret);
        }
Beispiel #9
0
        private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileName = new OpenFileDialog();

            fileName.InitialDirectory = "c:\\";
            fileName.FilterIndex      = 2;
            fileName.RestoreDirectory = true;
            if (fileName.ShowDialog() == DialogResult.OK)
            {
                Image pic = Image.FromFile(fileName.FileName);
                Pic = new myPicture((Bitmap)pic, fileName.FileName);
                this.rawPictureDisplay.Image = Pic.picture;
            }
        }
Beispiel #10
0
 //输入:锐化和二值化后的图像,r是擦除时使用的半径长度,x,y是圆心位置
 public findTick(myPicture Pic, int r, int x, int y)
 {
     width  = Pic.width;
     height = Pic.height;
     gray   = new int[width, height];
     for (int i = 0; i < width; i++)
     {
         for (int j = 0; j < height; j++)
         {
             gray[i, j] = Pic.grayDegree[i, j];
         }
     }
     radius   = r;
     circle_x = x;
     circle_y = y;
 }
Beispiel #11
0
        public myPicture doSmooth(myPicture input)
        {
            Bitmap ret = new Bitmap(input.width, input.height);

            for (int i = 0; i < input.width; ++i)
            {
                for (int j = 0; j < input.height; ++j)
                {
                    List <pair> tmp = new List <pair>();
                    for (int ii = 0; ii < 5; ++ii)
                    {
                        for (int jj = 0; jj < 5; ++jj)
                        {
                            int ni = i + dx[ii];
                            int nj = j + dy[jj];
                            if (ni == i && nj == j)
                            {
                                continue;
                            }
                            if (ni < 0 || ni >= input.width)
                            {
                                continue;
                            }
                            if (nj < 0 || nj >= input.height)
                            {
                                continue;
                            }
                            int d = input.grayDegree[ni, nj] - input.grayDegree[i, j];
                            if (d < 0)
                            {
                                d = -d;
                            }
                            tmp.Add(new pair(d, input.grayDegree[ni, nj]));
                        }
                    }
                    tmp.Sort(new pairCmp());
                    int sum = 0;
                    for (int k = 0; k < 5; ++k)
                    {
                        sum += tmp[k].y;
                    }
                    sum /= 5;
                    ret.SetPixel(i, j, Color.FromArgb(sum, sum, sum));
                }
            }
            return(new myPicture(ret, input.path));
        }
Beispiel #12
0
 //输入:锐化和二值化后的图像,r是找到的圆环半径,x,y是圆心位置
 public eraseCircleElement(myPicture Pic, int r, int x, int y)
 {
     width  = Pic.width;
     height = Pic.height;
     gray   = new int[width, height];
     for (int i = 0; i < width; i++)
     {
         for (int j = 0; j < height; j++)
         {
             gray[i, j] = Pic.grayDegree[i, j];
         }
     }
     res      = new Bitmap(width, height);
     radius   = r;
     circle_x = x;
     circle_y = y;
 }
        //输入:对最大连通块锐化后的图像,即变成两个同心圆,输出:内层圆
        public myPicture doHough(myPicture input)
        {
            int    width = input.width, height = input.height;
            Bitmap res = new Bitmap(width, height);
            int    sx = width / 2, sy = height / 2;

            //找到内层圆上的一个像素点
            for (int i = sx; i >= 0; i--)
            {
                if (input.grayDegree[i, sy] == 255)
                {
                    sx = i;
                    break;
                }
            }
            //初始化
            gray = new int[width, height];
            vis  = new int[width, height];
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    gray[i, j] = input.grayDegree[i, j];
                    vis[i, j]  = 0;
                }
            }
            //dfs找内层圆
            dfs(sx, sy, 1);
            //修改图像
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    if (vis[i, j] == 1)
                    {
                        res.SetPixel(i, j, Color.FromArgb(255, 255, 255));
                    }
                    else
                    {
                        res.SetPixel(i, j, Color.FromArgb(0, 0, 0));
                    }
                }
            }
            return(new myPicture(res));
        }
        public myPicture doSmooth(myPicture input)
        {
            Bitmap ret = new Bitmap(input.width, input.height);

            for (int i = 0; i < input.width; ++i)
            {
                for (int j = 0; j < input.height; ++j)
                {
                    int        cnt = 0;
                    List <int> tmp = new List <int>();
                    for (int ii = 0; ii < 3; ++ii)
                    {
                        for (int jj = 0; jj < 3; ++jj)
                        {
                            int ni = i + dx[ii];
                            int nj = j + dy[jj];
                            if (ni == i && nj == j)
                            {
                                continue;
                            }
                            if (ni < 0 || ni >= input.width)
                            {
                                continue;
                            }
                            if (nj < 0 || nj >= input.height)
                            {
                                continue;
                            }
                            ++cnt;
                            tmp.Add(input.grayDegree[ni, nj]);
                        }
                    }
                    tmp.Sort();
                    int val = tmp[cnt / 2];
                    ret.SetPixel(i, j, Color.FromArgb(val, val, val));
                }
            }
            return(new myPicture(ret, input.path));
        }
Beispiel #15
0
        public myPicture doSmooth(myPicture input)
        {
            Bitmap ret = new Bitmap(input.width, input.height);

            for (int i = 0; i < input.width; ++i)
            {
                for (int j = 0; j < input.height; ++j)
                {
                    int cnt = 0;
                    int sum = 0;
                    for (int ii = 0; ii < 3; ++ii)
                    {
                        for (int jj = 0; jj < 3; ++jj)
                        {
                            int ni = i + dx[ii];
                            int nj = j + dy[jj];
                            if (ni == i && nj == j)
                            {
                                continue;
                            }
                            if (ni < 0 || ni >= input.width)
                            {
                                continue;
                            }
                            if (nj < 0 || nj >= input.height)
                            {
                                continue;
                            }
                            ++cnt;
                            sum += input.grayDegree[ni, nj];
                        }
                    }
                    sum /= cnt;
                    ret.SetPixel(i, j, Color.FromArgb(sum, sum, sum));
                }
            }

            return(new myPicture(ret, input.path));
        }
Beispiel #16
0
        public myPicture doSharp(myPicture input)
        {
            Bitmap ret = new Bitmap(input.width, input.height);

            for (int i = 0; i < input.width; ++i)
            {
                for (int j = 0; j < input.height; ++j)
                {
                    int d1 = input.getGrayDegree(i, j) - input.getGrayDegree(i - 1, j - 1);
                    int d2 = input.getGrayDegree(i, j) - input.getGrayDegree(i + 1, j - 1);
                    if (d1 < 0)
                    {
                        d1 = -d1;
                    }
                    if (d2 < 0)
                    {
                        d2 = -d2;
                    }
                    int d = Math.Max(d1, d2);
                    ret.SetPixel(i, j, Color.FromArgb(d, d, d));
                }
            }
            return(new myPicture(ret, input.path));
        }
Beispiel #17
0
        public myPicture doSharp(myPicture input)
        {
            Bitmap ret = new Bitmap(input.width, input.height);

            for (int i = 0; i < input.width; ++i)
            {
                for (int j = 0; j < input.height; ++j)
                {
                    int val1 = -5 * input.getGrayDegree(i - 1, j - 1) + 3 * input.getGrayDegree(i - 1, j) + 3 * input.getGrayDegree(i - 1, j + 1) - 5 * input.getGrayDegree(i, j - 1) + 3 * input.getGrayDegree(i, j + 1) - 5 * input.getGrayDegree(i + 1, j - 1) + 3 * input.getGrayDegree(i + 1, j) + 3 * input.getGrayDegree(i + 1, j + 1);
                    int val2 = +3 * input.getGrayDegree(i - 1, j - 1) + 3 * input.getGrayDegree(i - 1, j) + 3 * input.getGrayDegree(i - 1, j + 1) - 5 * input.getGrayDegree(i, j - 1) + 3 * input.getGrayDegree(i, j + 1) - 5 * input.getGrayDegree(i + 1, j - 1) - 5 * input.getGrayDegree(i + 1, j) + 3 * input.getGrayDegree(i + 1, j + 1);
                    int val3 = +3 * input.getGrayDegree(i - 1, j - 1) + 3 * input.getGrayDegree(i - 1, j) + 3 * input.getGrayDegree(i - 1, j + 1) + 3 * input.getGrayDegree(i, j - 1) + 3 * input.getGrayDegree(i, j + 1) - 5 * input.getGrayDegree(i + 1, j - 1) - 5 * input.getGrayDegree(i + 1, j) - 5 * input.getGrayDegree(i + 1, j + 1);
                    int val4 = +3 * input.getGrayDegree(i - 1, j - 1) + 3 * input.getGrayDegree(i - 1, j) + 3 * input.getGrayDegree(i - 1, j + 1) + 3 * input.getGrayDegree(i, j - 1) - 5 * input.getGrayDegree(i, j + 1) + 3 * input.getGrayDegree(i + 1, j - 1) - 5 * input.getGrayDegree(i + 1, j) - 5 * input.getGrayDegree(i + 1, j + 1);
                    int val5 = +3 * input.getGrayDegree(i - 1, j - 1) + 3 * input.getGrayDegree(i - 1, j) - 5 * input.getGrayDegree(i - 1, j + 1) + 3 * input.getGrayDegree(i, j - 1) - 5 * input.getGrayDegree(i, j + 1) + 3 * input.getGrayDegree(i + 1, j - 1) + 3 * input.getGrayDegree(i + 1, j) - 5 * input.getGrayDegree(i + 1, j + 1);
                    int val6 = +3 * input.getGrayDegree(i - 1, j - 1) - 5 * input.getGrayDegree(i - 1, j) - 5 * input.getGrayDegree(i - 1, j + 1) + 3 * input.getGrayDegree(i, j - 1) - 5 * input.getGrayDegree(i, j + 1) + 3 * input.getGrayDegree(i + 1, j - 1) + 3 * input.getGrayDegree(i + 1, j) + 3 * input.getGrayDegree(i + 1, j + 1);
                    int val7 = -5 * input.getGrayDegree(i - 1, j - 1) - 5 * input.getGrayDegree(i - 1, j) - 5 * input.getGrayDegree(i - 1, j + 1) + 3 * input.getGrayDegree(i, j - 1) + 3 * input.getGrayDegree(i, j + 1) + 3 * input.getGrayDegree(i + 1, j - 1) + 3 * input.getGrayDegree(i + 1, j) + 3 * input.getGrayDegree(i + 1, j + 1);
                    int val8 = -5 * input.getGrayDegree(i - 1, j - 1) - 5 * input.getGrayDegree(i - 1, j) + 3 * input.getGrayDegree(i - 1, j + 1) - 5 * input.getGrayDegree(i, j - 1) + 3 * input.getGrayDegree(i, j + 1) + 3 * input.getGrayDegree(i + 1, j - 1) + 3 * input.getGrayDegree(i + 1, j) + 3 * input.getGrayDegree(i + 1, j + 1);
                    int val  = 0;
                    if (val1 < 0)
                    {
                        val1 = -val1;
                    }
                    if (val2 < 0)
                    {
                        val2 = -val2;
                    }
                    if (val3 < 0)
                    {
                        val3 = -val3;
                    }
                    if (val4 < 0)
                    {
                        val4 = -val4;
                    }
                    if (val5 < 0)
                    {
                        val5 = -val5;
                    }
                    if (val6 < 0)
                    {
                        val6 = -val6;
                    }
                    if (val7 < 0)
                    {
                        val7 = -val7;
                    }
                    if (val8 < 0)
                    {
                        val8 = -val8;
                    }
                    if (val1 > val)
                    {
                        val = val1;
                    }
                    if (val2 > val)
                    {
                        val = val2;
                    }
                    if (val3 > val)
                    {
                        val = val3;
                    }
                    if (val4 > val)
                    {
                        val = val4;
                    }
                    if (val5 > val)
                    {
                        val = val5;
                    }
                    if (val6 > val)
                    {
                        val = val6;
                    }
                    if (val7 > val)
                    {
                        val = val7;
                    }
                    if (val8 > val)
                    {
                        val = val8;
                    }
                    if (val > 255)
                    {
                        val = 255;
                    }
                    ret.SetPixel(i, j, Color.FromArgb(val, val, val));
                }
            }
            return(new myPicture(ret, input.path));
        }
Beispiel #18
0
        //利用OTSU算法实现二值化
        //输入:input为灰度图像
        //输出:res为二值图像
        //选取的阈值使分割出的两类像素,类间方差最大,类内方差最小
        public myPicture doOTSU(myPicture input)
        {
            Bitmap res = new Bitmap(input.width, input.height);

            int [,,] count = new int[40, 40, 256];
            int MAGIC = 300;

            for (int i = 0; i < input.width; ++i)
            {
                for (int j = 0; j < input.height; ++j)
                {
                    count[i / MAGIC, j / MAGIC, input.grayDegree[i, j]]++;
                }
            }

            for (int i = 0; i < input.width; i += MAGIC)
            {
                for (int j = 0; j < input.height; j += MAGIC)
                {
                    int    ii = i / MAGIC;
                    int    jj = j / MAGIC;
                    double n1, n2, n, sum1, sum2, sum;
                    n1   = 0;
                    n    = 0;
                    sum1 = 0;
                    sum  = 0;
                    for (int t = 0; t < 256; ++t)
                    {
                        int val = count[ii, jj, t];
                        sum += 1.0 * t * val;
                        n   += val;
                    }
                    double maxVal    = -1.0;
                    int    threshold = -1;
                    for (int t = 0; t < 256; ++t)
                    {
                        int val = count[ii, jj, t];
                        n1 += val;
                        if (n1 == 0)
                        {
                            continue;
                        }
                        n2 = n - n1;
                        if (n2 == 0)
                        {
                            break;
                        }
                        sum1 += 1.0 * t * val;
                        sum2  = sum - sum1;
                        double m1  = sum1 / n1;
                        double m2  = sum2 / n2;
                        double tmp = n1 * n2 * (m1 - m2) * (m1 - m2);
                        if (tmp > maxVal)
                        {
                            maxVal    = tmp;
                            threshold = t;
                        }
                    }
                    for (int p = i; p < Math.Min(i + MAGIC, input.width); ++p)
                    {
                        for (int q = 0; q < Math.Min(j + MAGIC, input.height); ++q)
                        {
                            if (input.grayDegree[p, q] <= threshold)
                            {
                                res.SetPixel(p, q, Color.FromArgb(0, 0, 0));
                            }
                            else
                            {
                                res.SetPixel(p, q, Color.FromArgb(255, 255, 255));
                            }
                        }
                    }
                }
            }

            return(new myPicture(res));
        }
Beispiel #19
0
        //计算圆的圆心,输入为自定义图片类input,输出为三元组(x,y,r)
        //对input的限制:只包含单圆环
        public circle doFind(myPicture input)
        {
            //从圆周上对称取10组点
            int cnt = 0;

            LinkedList <myPair> arr = new LinkedList <myPair>();

            for (int i = 2; i < input.width; i += 8)
            {
                for (int j = 5; j < input.height; ++j)
                {
                    if (input.grayDegree[i, j] == 255)
                    {
                        cnt++;
                        arr.AddLast(new myPair(i, j));
                        for (int k = input.height - 5; k >= 0; --k)
                        {
                            if (input.grayDegree[i, k] == 255)
                            {
                                arr.AddLast(new myPair(i, k));
                                break;
                            }
                        }
                        break;
                    }
                }
                if (cnt == 10)
                {
                    break;
                }
            }

            //最小二乘法求解圆心
            A  = new matrix(2 * cnt, 3);
            AT = new matrix(3, 2 * cnt);
            B  = new matrix(2 * cnt, 1);

            int cur = 0;

            foreach (myPair p in arr)
            {
                int x = p.x;
                int y = p.y;
                A.a[cur, 0]  = x;
                A.a[cur, 1]  = y;
                A.a[cur, 2]  = 1;
                AT.a[0, cur] = x;
                AT.a[1, cur] = y;
                AT.a[2, cur] = 1;
                B.a[cur, 0]  = 1.0 * x * x + 1.0 * y * y;
                cur++;
            }

            matrix coef = AT.doMul(A);
            matrix b    = AT.doMul(B);

            matrix mat = new matrix(3, 4);

            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    mat.a[i, j] = coef.a[i, j];
                }
            }

            mat.a[0, 3] = b.a[0, 0];
            mat.a[1, 3] = b.a[1, 0];
            mat.a[2, 3] = b.a[2, 0];

            return(cal(mat));
        }
Beispiel #20
0
 public inPut(myPicture _Pic)
 {
     Pic = _Pic;
     InitializeComponent();
 }
Beispiel #21
0
        //函数功能:对main.cs传入的图像进行处理,并将结果传递到ans.cs显示
        public void domain()
        {
            //处理输入
            double low  = 0.0;
            double high = 1.0;

            try
            {
                low  = Convert.ToDouble(smallInput.Text);
                high = Convert.ToDouble(largeInput.Text);
            }
            catch
            {
                return;
            }


            OTSU B = new OTSU();
            //锐化、二值化
            myPicture ret = B.doOTSU(sharp4.doSharp(Pic));
            myPicture res = ret;
            //找圆心之前的预处理
            findCircleInit circle = new findCircleInit();

            ret = circle.init(ret);
            ret = sharp4.doSharp(ret);
            ret = circle.doHough(ret);

            //找圆心
            circle o = new findCircleCenter().doFind(ret);

            //找指针
            ret = new findLineInit().doFind(Pic, o);
            myPicture tmp = sharp1.doSharp(ret);

            tmp = smooth2.doSmooth(tmp);
            tmp = B.doOTSU(tmp);
            RANSAC R = new RANSAC();
            myPair L = R.doFind(smooth2.doSmooth(B.doOTSU(sharp4.doSharp(Pic))), R.doRANSAC(tmp, new myPair((int)o.x, (int)o.y)), o);


            //找刻度线的预处理
            eraseCircleElement ECE = new eraseCircleElement(res, (int)o.r, (int)o.x, (int)o.y);
            int r = ECE.solve();

            res = ECE.erase(r - 1);

            //找到左右两端的刻度线
            findTick ticks = new findTick(res, r - 1, (int)o.x, (int)o.y);
            myPair   left = ticks.FindLeft(), right = ticks.FindRight();

            //求角度
            double thta = 2 * Math.PI - angle(left, right, o);
            double alpha;

            if (L.x <= o.x)
            {
                alpha = angle(left, L, o);
            }
            else
            {
                alpha = thta - angle(L, right, o);
            }
            double ans = low + (high - low) * (alpha + Math.PI / 180) / thta;

            Form newForm = new ans(ans);

            newForm.ShowDialog();
            newForm.Dispose();
        }
Beispiel #22
0
        //函数功能:确定仪表盘指针的方向向量
        //输入:二值图像input,直线方程ret,仪表盘中心o
        //输出:仪表盘指针上的某一个点
        public myPair doFind(myPicture input, line ret, circle o)
        {
            if (Math.Abs(ret.B) < 0.000001)
            {
                return(new myPair((int)o.x, 0));
            }

            int    MAGIC = (int)(input.width * 0.18);
            int    cnt1 = 0, cnt2 = 0;
            double K = -ret.A / ret.B;
            double B = -ret.C / ret.B;

            for (int dx = 1; dx <= MAGIC; ++dx)
            {
                double x  = o.x + dx;
                double y  = K * x + B;
                int    xx = (int)x;
                int    yy = (int)y;
                if (xx + 2 >= input.width || xx - 2 < 0)
                {
                    break;
                }
                if (yy + 2 >= input.height || yy - 2 < 0)
                {
                    break;
                }
                for (int i = -2; i <= 2; ++i)
                {
                    for (int j = -2; j <= 2; ++j)
                    {
                        if (input.grayDegree[(int)(x + i), (int)(y + j)] == 255)
                        {
                            cnt1++;
                        }
                    }
                }
            }

            for (int dx = 1; dx <= MAGIC; ++dx)
            {
                double x  = o.x - dx;
                double y  = K * x + B;
                int    xx = (int)x;
                int    yy = (int)y;
                if (xx + 2 >= input.width || xx - 2 < 0)
                {
                    break;
                }
                if (yy + 2 >= input.height || yy - 2 < 0)
                {
                    break;
                }
                for (int i = -2; i <= 2; ++i)
                {
                    for (int j = -2; j <= 2; ++j)
                    {
                        if (input.grayDegree[(int)(x + i), (int)(y + j)] == 255)
                        {
                            cnt2++;
                        }
                    }
                }
            }

            if (cnt1 > cnt2)
            {
                double x = o.x + MAGIC;
                double y = K * x + B;
                return(new myPair((int)x, (int)y));
            }
            else
            {
                double x = o.x - MAGIC;
                double y = K * x + B;
                return(new myPair((int)x, (int)y));
            }
        }
Beispiel #23
0
        //函数功能:利用RANSAC算法从图像中提取直线,RANSAC对噪声敏感度小
        //输入:二值化图像input,目标直线的一个端点center
        //输出:目标直线方程
        public line doRANSAC(myPicture input, myPair center)
        {
            LinkedList <myPair> arr = new LinkedList <myPair>();

            for (int i = 0; i < input.width; ++i)
            {
                for (int j = 0; j < input.height; ++j)
                {
                    if (input.grayDegree[i, j] == 255)
                    {
                        arr.AddLast(new myPair(i, j));
                    }
                }
            }

            Random rd        = new Random(13);
            line   ret       = new line(0, 0, 0);
            double besterror = 1000000000000;
            int    bound     = (int)(0.07 * arr.Count);

            for (int iter = 0; iter < 100; ++iter)
            {
                int    sampleIndex = rd.Next() % arr.Count;
                myPair sample      = arr.ElementAt(sampleIndex);
                line   cur         = new line(center, sample);
                LinkedList <myPair> alsoinliers = new LinkedList <myPair>();
                foreach (myPair p in arr)
                {
                    double d = cur.distance(p);
                    if (d <= 4)
                    {
                        alsoinliers.AddLast(p);
                    }
                }

                if (alsoinliers.Count >= bound)
                {
                    alsoinliers.AddLast(sample);
                    line   better    = calLine(alsoinliers);
                    double thiserror = 0;
                    foreach (myPair p in alsoinliers)
                    {
                        double dis = better.distance(p);
                        thiserror += dis * dis;
                    }
                    thiserror /= alsoinliers.Count;
                    if (thiserror < besterror)
                    {
                        besterror = thiserror;
                        ret       = better;
                    }
                }
            }

            return(ret);

            /*
             * for (int i = 0; i < input.width; ++i)
             * {
             *  for (int j = 0; j < input.height; ++j)
             *  {
             *      double val = Math.Abs(ret.A * i + ret.B * j + ret.C);
             *      if (val <= 1)
             *      {
             *          input.picture.SetPixel(i, j, Color.FromArgb(255, 0, 0));
             *      }
             *  }
             * }
             */
            //return input;
        }