一、先是在程序中圖像的導入,我是根據圖像路徑實現,其中path是string類型,是圖像路徑。
IntPtr img=CvInvoke.cvLoadImage(path, Emgu.CV.CvEnum.LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_ANYCOLOR);
二、圖像灰度化處理,先創建一幅尺寸大小為為原圖的8位圖像GrayImg1:
Rectangle cr = CvInvoke.cvGetImageROI(img1);
??????????????? int width = cr.Width;
??????????????? int height = cr.Height;
IntPtr GrayImg1 = CvInvoke.cvCreateImage(cr.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1);
現在就能使用cvCvtColor函數實現灰度化:
CvInvoke.cvCvtColor(img1, GrayImg1, Emgu.CV.CvEnum.COLOR_CONVERSION.CV_BGR2GRAY);
三、直方圖的創建,并獲取數據
int[] hist_size = new int[1] { 256 };//建一個數組來存放直方圖數據
IntPtr HistImg=CvInvoke.cvCreateHist(1, hist_size, Emgu.CV.CvEnum.HIST_TYPE.CV_HIST_ARRAY, null, 1);//創建了一個空的直方圖
CvInvoke.cvCalcHist(inPtr1, HistImg,false,System.IntPtr.Zero);//計算inPtr1指向圖像的數據,并傳入Histimg中,其中IntPtr[] inPtr1 = new IntPtr[1] { SubImg}。
現在要獲取Histimg中的具體數據:
for (int i = 0; i < 256; i++)
??????????? {
??????????????? temphist[i] = CvInvoke.cvQueryHistValue_1D(histImg, i);
??????????? }
這樣在數組temphist中保存了直方圖數據。
四、對第一步中由cvLoadImage導入的圖像進行像素點的操作。由于img 是IntPtr類型無法直接進行操作,所以首先要進行格式的轉化,把IntPtr型轉換成MIplImage:
Emgu.CV.Structure.MIplImage MIpImg =
(Emgu.CV.Structure.MIplImage)System.Runtime.InteropServices.Marshal.PtrToStructure(img, typeof(Emgu.CV.Structure.MIplImage));
然后再C#中使用unsafe中指針操作:npixel = (int)((byte*)img.imageData + img.widthStep * i)[j];
五、IntPtr Dyncontour = new IntPtr();//存放檢測到的圖像塊的首地址
IntPtr Dynstorage = CvInvoke.cvCreateMemStorage(0);開辟內存區域
int n= CvInvoke.cvFindContours(tempimg, Dynstorage, ref Dyncontour, StructSize.MCvContour, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_CCOMP,Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, new Point(0, 0));
n表示檢測到不為零區域的個數。
六、對第五步檢測到的區域繪制輪廓
for(;DyncontourTemp!=null&&DyncontourTemp.Ptr.ToInt32()!=0;DyncontourTemp=DyncontourTemp.HNext)
{
CvInvoke.cvDrawContours(tempContImg, DyncontourTemp,new MCvScalar(255, 255, 255),new MCvScalar(255, 255, 255), 0, 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));
?}
其中的DyncontourTemp為
Seq<Point> DyncontourTemp1= new Seq<Point>(Dyncontour, null);//方便對IntPtr類型進行操作
Seq<Point> DyncontourTemp=DyncontourTemp1;
七、對第五步檢測出的區域的坐標提取,通過cvFindContours函數的調用在 Dyncontour中存放的是不為零區域坐標的值存儲在內存中的首地址指針。
seq<Point> DyncontourTemp1= new Seq<Point>(Dyncontour, null); //方便對IntPtr類型進行操作
int total=contourImg.Total;//contourImg包含的元素的總數
?int TempX = 0; ?int TempY = 0;int[,] contourArray = new int[2,total];
?//獲得輪廓的坐標值
?for (int i = 0; i < total;i++ )
{
? contourArray[0,i]=contourImg[i].X;
? contourArray[1,i]=contourImg[i].Y;
?}