假定你有一定的C#编程基础。下面代码是显示一幅bmp图像(默认是8位灰度图像,即0-255灰度的黑白色)
string path = Environment.CurrentDirectory;//获取debug路径
Bitmap curBitmap = (Bitmap)Bitmap.FromFile(path + “\contour2.bmp”);//debug路径下有图像contour2.bmp
pictureBox1.Image = curBitmap;//在图像控件显示contour2.bmp
以上三句话,放在form()中。想要得到这幅图的像素颜色灰度buffer,在formload()中执行以下操作:
int ww = curBitmap.Width;//此处又用到位图,所以位图声明全局
int hh = curBitmap.Height;
int bytes = ww * hh ;
byte[] rgbValues = new byte[bytes];
byte[] glob_buffer8 = new byte[ww * hh];//此变量也要声明全局
Rectangle rc = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
System.Drawing.Imaging.BitmapData bmpdata = curBitmap.LockBits(rc, System.Drawing.Imaging.ImageLockMode.ReadWrite,curBitmap.PixelFormat);
IntPtr imageptr = bmpdata.Scan0; System.Runtime.InteropServices.Marshal.Copy(imageptr, rgbValues, 0, bytes);//像素颜色灰度在rgbValues中
curBitmap.UnlockBits(bmpdata);
glob_buffer8 = rgbValues;//给全局
完成以上两步,然后制作感兴趣区域(ROI),大家都有这样的体验,在windows窗口,按着鼠标不放,拖动一下,就会出现一个矩形虚线框,没错,就是他,他就是感兴趣区域(roi),我们经常什么也没圈到,晃一下就没了,或许叫无聊区更合适,因为大家经常对着电脑窗口发呆无聊时,经常这样搞。事情往往就是这样,无发现,无作为,一旦发现,便拥有了世界。
再看roi截取到的细节图像,
然后实现步骤如下:
一, public ROIsimple m_cutImageRoi;//声明感兴趣区域(ROI)
二,form()中初始化,m_cutImageRoi = new ROIsimple();
三, private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
PointF point = new PointF(e.X, e.Y);
bool status = false;
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
status = true;
}
m_cutImageRoi.DrawRectFrame(status, point);//用来感知两个操作
this.Cursor = m_cutImageRoi.m_cur;//改变鼠标的样子
pictureBox1.Invalidate(false);
}
四,m_cutImageRoi.m_RoiBase1.Draw(g, p,”ROI”,true);//在paint()函数中画出感兴趣区域(ROI)
ROIsimple 是个什么鬼们来看一看,
public class ROIsimple
{
public RoiBase1 m_RoiBase1;//封装了一个矩形及对矩形的操作
public E_HANDLES m_eHandle;//鼠标位置
public Cursor m_cur;//改变鼠标形状
public ROIsimple()
{
m_RoiBase1 = new RoiBase1();
m_cur = Cursors.Arrow;//鼠标通用箭形状
}
public void DrawRectFrame(bool lbtn, PointF point)//用来感知两个操作
{
if (lbtn)
{
switch (m_eHandle)
{
case E_HANDLES.E_HANDLE_INSIDE:
m_RoiBase1.Drag(point);//左键按下拖住中心移动
break;
case E_HANDLES.E_HANDLE_SOUTH_EAST:
{
m_RoiBase1.DragTolerance(point);//左键按下拖住矩形右下角改变大小
}
break;
default:
break;
}
}
else
{
m_eHandle = (E_HANDLES)m_RoiBase1.IsPointInRect(point);
}
Insteadof((int)m_eHandle);//改变鼠标的样子
return;
}
private void Insteadof(int intcursor)//改变鼠标的样子
{
switch (intcursor)
{
case (int)E_HANDLES.E_HANDLE_INSIDE:
m_cur = Cursors.SizeAll;
break;
case (int)E_HANDLES.E_HANDLE_NORTH:
case (int)E_HANDLES.E_HANDLE_SOUTH:
m_cur = Cursors.SizeNS;
break;
case (int)E_HANDLES.E_HANDLE_EAST:
case (int)E_HANDLES.E_HANDLE_WEST:
m_cur = Cursors.SizeWE;
break;
case (int)E_HANDLES.E_HANDLE_NORTH_WEST:
case (int)E_HANDLES.E_HANDLE_SOUTH_EAST:
m_cur = Cursors.SizeNWSE;
break;
case (int)E_HANDLES.E_HANDLE_NORTH_EAST:
case (int)E_HANDLES.E_HANDLE_SOUTH_WEST:
m_cur = Cursors.SizeNESW;
break;
default:
m_cur = Cursors.Arrow;//鼠标通用箭形状
break;
}
return;
}
}
public enum E_HANDLES//矩形框的八个方向和中心
{
E_HANDLE_NONE,//0
E_HANDLE_INSIDE,//1
E_HANDLE_NORTH,//2
E_HANDLE_EAST,//3
E_HANDLE_SOUTH,//4
E_HANDLE_WEST,//5
E_HANDLE_NORTH_WEST,//6
E_HANDLE_SOUTH_WEST,//7
E_HANDLE_NORTH_EAST,//8
E_HANDLE_SOUTH_EAST,//9
E_HANDLE_UNKNOWN = 65535
};
m_RoiBase1是个什么鬼们来看一看,
public class RoiBase1//实质就是画了一个矩形
{
public RectangleF rcWin;
public PointF m_Center;
public RoiBase1()
{
rcWin = new RectangleF(100, 100, 100, 100);//矩形框初始化的位置
m_Center.X = rcWin.Left + rcWin.Width / 2;//矩形框的中心
m_Center.Y = rcWin.Top + rcWin.Height / 2;
}
public void ResetRc(RectangleF rc)
{
rcWin = rc;
m_Center.X = rcWin.Left + rcWin.Width / 2;
m_Center.Y = rcWin.Top + rcWin.Height / 2;
}
public void Draw(Graphics g, Pen p, string labelstr, bool b_minRc)
{//可以在矩形框上写字,譬如“ROI”,作为标签
g.DrawRectangle(p, rcWin.Left, rcWin.Top, rcWin.Width, rcWin.Height);
if (b_minRc)//鼠标形状改变区域画了两个10*10小矩形
{
g.DrawRectangle(p, (int)m_Center.X – 5, (int)m_Center.Y – 5, 10, 10);
g.DrawRectangle(p, (int)rcWin.Left + rcWin.Width – 5, (int)rcWin.Top + rcWin.Height – 5, 10, 10);
}
Font drawfont = new Font(“Arial”, 9);
g.DrawString(labelstr, drawfont, Brushes.Brown, rcWin.Left, (float)(rcWin.Top / 2.0 + rcWin.Bottom / 2.0) – 10);
}
public int IsPointInRect(PointF point)//判断鼠标位置
{
if (point.X = m_Center.X – 5
&& point.Y >= m_Center.Y – 5 && point.Y {
return (int)E_HANDLES.E_HANDLE_INSIDE;//经过判断在矩形中心位置//1
}
else if (point.X = rcWin.Left + rcWin.Width – 5
&& point.Y >= rcWin.Top + rcWin.Height – 5 && point.Y {
return (int)E_HANDLES.E_HANDLE_SOUTH_EAST;// E_HANDLE_SOUTH_EAST,//9
}//经过判断在矩形右下角位置
else
{
return 0;
}
}
public void Drag(PointF point)//左键按下拖住中心移动
{
float tempX = 0, tempY = 0;
tempX = point.X – m_Center.X;
tempY = point.Y – m_Center.Y;
m_Center.X = (float)point.X;
m_Center.Y = (float)point.Y;
rcWin = new RectangleF(rcWin.Left + tempX, rcWin.Top + tempY, rcWin.Width, rcWin.Height);
}
public void DragTolerance(PointF point)//左键按下拖住矩形右下角改变大小
{
rcWin.Width = point.X – rcWin.Left;
rcWin.Height = point.Y – rcWin.Top;
rcWin = new RectangleF(rcWin.Left, rcWin.Top, rcWin.Width, rcWin.Height);
m_Center.X = rcWin.Left + rcWin.Width / 2;
m_Center.Y = rcWin.Top + rcWin.Height / 2;
}
}
以上完成了图像上画一个可以互动的感兴趣区域(ROI),现在添加一个按钮,来截取感兴趣区域(ROI)图像放入pictureBoxRoiImg图像控件。
private void cutroi_Click(object sender, EventArgs e)
{
_RoiW = Convert.ToInt32(textBoxW.Text);//感兴趣区域的宽度
int mod = _RoiW % 4;//解决四位对齐问题20150716
_RoiW = _RoiW + (4 – mod) % 4;
_RoiH = Convert.ToInt32(textBoxH.Text);//感兴趣区域的高度
_RoiX = Convert.ToInt32(textBoxX.Text);感兴趣区域的坐标(x,y)在图像中位置
_RoiY = Convert.ToInt32(textBoxY.Text);
tempImage3 = new byte[_RoiW * _RoiH]; //截取的感兴趣图像
int H = curBitmap.Height;//加载bmp图像的高和宽
int W = curBitmap.Width;
for (int i = 0; i for (int j = 0; j {
tempImage3[i * _RoiW + j] = glob_buffer8[((i + _RoiY) * W + j + _RoiX)];
}
//显示截取的感兴趣图像
byte[] cutvalues = new byte[_RoiW * _RoiH * 3];
int bytes = _RoiW * _RoiH * 3;
Bitmap cutPic24 = new Bitmap(_RoiW, _RoiH, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
BitmapData _cutPic = cutPic24.LockBits(new Rectangle(0, 0, _RoiW, _RoiH), ImageLockMode.ReadWrite,
cutPic24.PixelFormat);
IntPtr ptr = _cutPic.Scan0;//得到首地址
for (int i = 0; i {
for (int j = 0; j {
int n = i * _RoiW + j;
int m = 3 * n;
cutvalues[m] = tempImage3[n];
cutvalues[m + 1] = tempImage3[n];
cutvalues[m + 2] = tempImage3[n];
}
}
//把cutvalues数组给ptr
System.Runtime.InteropServices.Marshal.Copy(cutvalues, 0, ptr, _RoiH * _RoiW * 3);
cutPic24.UnlockBits(_cutPic);
pictureBoxRoiImg.Image = cutPic24;
///
}
(待续………………….)
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!