Emgucv不完整图像分割试验(四)——Imagebox控件坐标转图片坐标

书接上文Emgucv不完整图像分割试验(三),将图切割N个小块后如何在Imagebox内选中所需要的小块的问题就浮上来了,

本来是一个很简单的问题,但如果加上滑动条和缩放后,整个事情就变得变态起来了。。。


涉及的数值太多,画了上面个图辅助说明。

A:现在图的尺寸(假定有放大缩小)

B:ImageBox的尺寸(假定随窗口一起变化)

C:鼠标相对ImageBox的坐标(这个也就是我们直接获取的数据,然后用它推导最后的落点)

D\E:水平和垂直滑动条的高度和宽度(这个很变态的,出现的时候,之前的B的数值也会被修改,切切记住)

F\G:水平和垂直滑动条当前的数值

H\I:水平和垂直滑动条的最大值(不是直接取到的那个数值,而是真实滑到最后的值,两者很大可能是不等的)

J:图片的缩放比


目标:将C的坐标换算到真实的(没缩放)的图片的坐标。步骤如下:

1:A-B,获取假如图片拉到底,超出的宽和高(用于后面计算滑动条的步长)

2:判断是否有滑动条,如果有,就修正,分别减去D,E的数值,因为有了滑动条则ImageBox的显示区也就变化了。

3:修正H,I的数值(原先的MAX是Imagebox生成滑动条时自动生成的,但划到底一般不是原先的最大值,2和3两步卡了我整整一天。也是本贴的主要内容)

4:将1的值/3的值,算出一个滑动条数值+1相对移动的距离

5:用F,G和4算出的值+C的值算出当前当前点在缩放图的坐标。

6:用5的值和J的值算出最后C点在真实图坐标。(注意浮点数和整数的换算和向上取整)


代码修修补补弄出来,很乱,需要的同学最好自己重写下,或者有高手有更好的版本麻烦发我一份:

            //校准滑动条
            if (this.checkBox3.Checked)
            {
                    this.textBox7.Text = this.imageBox1.HorizontalScrollBar.Value.ToString();
                    this.textBox8.Text = this.imageBox1.VerticalScrollBar.Value.ToString();
            }

            //修正鼠标坐标为图片坐标
            if (this.checkBox2.Checked)
            {
                int originslWidth = this.imageBox1.Width;
                int originslHeight = this.imageBox1.Height;

                if (this.imageBox1.VerticalScrollBar.Width > 0)
                {
                    originslWidth = this.imageBox1.Width- this.imageBox1.VerticalScrollBar.Width;
                }
                if (this.imageBox1.HorizontalScrollBar.Height > 0)
                {
                    originslHeight = this.imageBox1.Height- this.imageBox1.HorizontalScrollBar.Height;
                }

                double currentWidth = this.imageBox1.Image.Bitmap.Width * this.imageBox1.ZoomScale;
                double currentHeight = this.imageBox1.Image.Bitmap.Height * this.imageBox1.ZoomScale;

                double black_left = 0;
                double black_top = 0;

                if (currentWidth > originslWidth)
                {
                    black_left = currentWidth - originslWidth;
                }
                if (currentHeight > originslHeight)
                {
                    black_top= currentHeight - originslHeight;
                }

                double currentblack_leftstep = 0;
                double currentblack_topstep = 0;

                int maxH = 100;
                int maxV = 100;

                if (this.textBox7.Text != "")
                {
                    maxH = Convert.ToInt32(this.textBox7.Text); }
                if (this.textBox8.Text != "")
                {
                    maxV = Convert.ToInt32(this.textBox8.Text); }

                if (this.imageBox1.HorizontalScrollBar.Maximum > 0)
                {
                    currentblack_leftstep = black_left / maxH;
                }

                if (this.imageBox1.VerticalScrollBar.Maximum > 0)
                {
                    currentblack_topstep = black_top / maxV;
                }

                double currentX = e.X;
                double currentY = e.Y;

                if(this.imageBox1.HorizontalScrollBar.Value>1)
                    currentX = currentblack_leftstep*(this.imageBox1.HorizontalScrollBar.Value) + e.X;
                if (this.imageBox1.VerticalScrollBar.Value > 1)
                    currentY = currentblack_topstep*(this.imageBox1.VerticalScrollBar.Value) + e.Y;



                int xx =Convert.ToInt32( Math.Ceiling(Convert.ToSingle(currentX / this.imageBox1.ZoomScale)));
                int yy = Convert.ToInt32(Math.Ceiling(Convert.ToSingle(currentY / this.imageBox1.ZoomScale)));

                PointF tempP = new PointF(xx, yy);           //后面我还做了其它,这里就不贴出了}

最后放个结果图,右下两个坐标,一个是鼠标单击的坐标,一个是最后换算的坐标(我的图尺寸为103*130,我点的是最右下)



初开博客,目的是交流与合作,本人QQ:273651820。


猜你喜欢

转载自blog.csdn.net/qq_26996385/article/details/81063271