c#调用c++(Opencv)dll的实例

*****************************************c++代码

MYDLL int GetCenterPos(uchar* imageData,int step, int widthValue, int heightValue, int BinaryThreshold, int LineBlankThreshold, int* centerX, int* centerY)
{
    
    //Mat src(widthValue, heightValue, CV_8UC3);
    //cvtColor(src, src, CV_RGB2GRAY);
    //memcpy(imageData, src.data, sizeof(uchar)*src.rows*src.cols * 3);
    Mat src = cv::Mat(heightValue, widthValue, CV_8UC4, imageData,step);//很重要的参数:CV_8UC4
    /*return src.cols;*/
    /*return src.rows;*/
    /*imshow("图1", src);*/
    /*return 99;*/
    
    int ImageWidth = src.cols;
    int ImageHeight = src.rows;
    /*Mat src ImageWidth= imread(path);*/
    // 结果图
    Mat dst;
    //灰度图转换
    cvtColor(src, dst, COLOR_RGB2GRAY);
    // 高斯模糊,主要用于降噪

    GaussianBlur(dst, dst, Size(3, 3), 0);
    
    // 二值化图,主要将灰色部分转成白色,使内容为黑色
    threshold(dst, dst, BinaryThreshold, 255, THRESH_BINARY_INV);

    // 中值滤波,同样用于降噪
    medianBlur(dst, dst, 3);
    //blur(dst, dst, Size(3, 3));//平滑处理
    
    //***********获取中心算法
    /*imshow("图2", dst);*/
    //********************************************横向遍历
    //map<int, int> horizonMap;//提取词典
    vector<int> vecMyHouse(0);
    vector<int> HorizonMyHouse(0);
    int height = dst.rows;
    int width = dst.cols;
    
    for (int i = 0; i < height; i++) {
        if (i % LineBlankThreshold == 0)
        {

            int num = 0;
            vecMyHouse.clear();
            
            for (int j = 0; j < width; j++) {
                int index = i * width + j;
                //像素值        
                int data = (int)dst.data[index];
                
                if (data == 0)
                {        
                    /*mp.X = j;
                    mp.Y = i;*/
                    
                    vecMyHouse.push_back(j);
                    
                }

            }
            
            //******
            int tempX = 0;
            int tempY = 0;
            int count = vecMyHouse.size();
            if (count > 50)
            {
                int a = 0;
            }
            if (vecMyHouse.size() <3)continue;
            if (vecMyHouse.size() > 20)continue;        
            //sort(vecMyHouse.begin(), vecMyHouse.end());//大小排序
            //最大值:            
            int max = *max_element(vecMyHouse.begin(), vecMyHouse.end());//过滤
            int min = *min_element(vecMyHouse.begin(), vecMyHouse.end());//过滤
            int tempCount = 0;
            //利用keySet方法将map中键放入到Set中,可以使用  增强for
            for (int k = 0; k < vecMyHouse.size(); k++) {
                if (vecMyHouse[k] != max&&vecMyHouse[k] != min)
                {
                    tempX += vecMyHouse[k];
                    tempCount++;
                }

            }
            int value = (int)(tempX*1.0 / tempCount);
            
            HorizonMyHouse.push_back(value);
            num++;
        }
    }
    int tempX = 0;
    //最大值:
    int max = *max_element(HorizonMyHouse.begin(), HorizonMyHouse.end());//过滤
    //最小值:
    int min = max;//*min_element(HorizonMyHouse.begin(), HorizonMyHouse.end());//过滤
    sort(HorizonMyHouse.begin(), HorizonMyHouse.end());//大小排序
    int count = HorizonMyHouse.size();
    for (int z = 0; z < HorizonMyHouse.size(); z++)
    {
        if (min>HorizonMyHouse[z] && HorizonMyHouse[z] != 0)
        {
            min = HorizonMyHouse[z];
        }
        tempX += HorizonMyHouse[z];
    }
    tempX = tempX - (max + min);
    if (HorizonMyHouse.size() > 2)
    {

        *centerX = (tempX *1.0 / (HorizonMyHouse.size() - 2));
    }
    else
    {
        *centerX = (HorizonMyHouse[0] + HorizonMyHouse[1]) / 2;
    }
    *centerX += 1;

    
#if 1
    //********************************************纵向遍历
    //map<int, int> horizonMap;//提取词典
    vector<int> vecMyHouse2(0);
    vector<int> verticalMyHouse(0);
    height = dst.rows;
    width = dst.cols;
    for (int i = 0; i < width; i++) {
        if (i % LineBlankThreshold == 0)
        {
            int num = 0;
            vecMyHouse2.clear();

            for (int j = 0; j < height; j++) {
                int index = j * width + i;
                //像素值        
                int data = (int)dst.data[index];
                if (data == 0)
                {
                /*    mp.X = i;
                    mp.Y = j;*/

                    vecMyHouse2.push_back(j);

                }

            }
            //******
            int tempX = 0;
            int tempY = 0;
            int count = vecMyHouse.size();
            if (vecMyHouse2.size() <3)continue;
            if (vecMyHouse2.size() > 20)continue;
            sort(vecMyHouse2.begin(), vecMyHouse2.end());//大小排序
            //最大值:
            int max = *max_element(vecMyHouse2.begin(), vecMyHouse2.end());//过滤
            int min = *min_element(vecMyHouse2.begin(), vecMyHouse2.end());//过滤
            int tempCount = 0;
            //利用keySet方法将map中键放入到Set中,可以使用  增强for
            for (int k = 0; k < vecMyHouse2.size(); k++) {
                if (vecMyHouse2[k] != max&&vecMyHouse2[k] != min)
                {
                    tempX += vecMyHouse2[k];
                    tempCount++;
                }


            }
            int value = (int)(tempX / tempCount);
            verticalMyHouse.push_back(value);
            num++;
            
        }
    }
    
    int tempY = 0;
    //最大值:
    max = *max_element(verticalMyHouse.begin(), verticalMyHouse.end());//过滤
    //最小值:
    min = max; //*min_element(verticalMyHouse.begin(), verticalMyHouse.end());//过滤
    for (int z = 0; z < verticalMyHouse.size(); z++)
    {
        if (min>verticalMyHouse[z] && verticalMyHouse[z] != 0)
        {
            min = verticalMyHouse[z];
        }
        tempY += verticalMyHouse[z];
    }
    
    tempY = tempY - (max + min);
    if (verticalMyHouse.size()>2)
    {
        *centerY = tempY / (verticalMyHouse.size() - 2);
    }
    else
    {
        *centerY = (verticalMyHouse[0] + verticalMyHouse[1]) / 2;
    }

    *centerY += 1;
#endif
        return 0;
}

**********************************C#代码

 public class ImageDll
    {
       [DllImport(@"G:\whh\2020\projectTest\c++\ImageAnalysis\ImageAnalysisTest2020.1.3\ImageAnalysisTest\x64\Debug\CrossDiscern.dll", EntryPoint = "GetCenterPos", CallingConvention = CallingConvention.Cdecl)]
       public static extern int GetCenterPos(IntPtr imageData,int step, int widthValue, int heightValue, int BinaryThreshold, int LineBlankThreshold, ref int centerX, ref int centerY);

       [DllImport(@"CrossDiscern.dll", EntryPoint = "Sum", CallingConvention = CallingConvention.Cdecl)]
       public static extern int Sum(int a, int b);

       //**********图片数据转换
       public static int GetPositionResult_XY(Bitmap bitmap,int BinaryThreshold, int LineBlankThreshold, ref int centerX, ref int centerY)
       {
#if false
           BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
           IntPtr pSt = bmpdata.Scan0;
           int bytes = bitmap.Width * bitmap.Height * 3;
           byte[] rgbValues = new byte[bytes];
           Marshal.Copy(pSt, rgbValues, 0, bytes);
          
           int res = GetCenterPos(rgbValues, bmpdata.Stride, bitmap.Width, bitmap.Height, BinaryThreshold, LineBlankThreshold, ref centerX, ref  centerY);
           bitmap.UnlockBits(bmpdata);
           return res;
#endif
#if true
           BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
           IntPtr pSt = bmpdata.Scan0;
           int bytes = bitmap.Width * bitmap.Height * 3;
           byte[] rgbValues = new byte[bytes];
           Marshal.Copy(pSt, rgbValues, 0, bytes);

           int res = GetCenterPos(pSt, bmpdata.Stride, bitmap.Width, bitmap.Height, BinaryThreshold, LineBlankThreshold, ref centerX, ref  centerY);
           bitmap.UnlockBits(bmpdata);
           return res;
#endif
       }

    }

c#调用

 private void button_GetCenterPos_Click(object sender, EventArgs e)
        {
            Bitmap map = new Bitmap(sourceImage);
            int x=0;
            int y=0;
           if( ImageDll.GetPositionResult_XY(map, 80, 20, ref x, ref y)==0)
           {
             
               //MessageBox.Show("识别成功!","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
               string content = "";//"图像大小:" + "\r\n";
               content += "起点:X=0 Y=0"+"\r\n";
               content +=( "终点:X=" + map.Width.ToString()+" Y="+map.Height.ToString()+"\r\n");
               content += "中线点:X=" + x.ToString() + " Y=" + y.ToString() + "\r\n";
               label4.Text = content;
               //*********绘制中心点
               Graphics graphics = panel3.CreateGraphics();
               Font font = new Font("宋体",16,FontStyle.Bold/*|FontStyle.Italic|FontStyle.Underline*/,GraphicsUnit.Point);//其中宋体是字体,24是字号,FontStyle的几个是字的样式,最后的GraphicsUnit是字的度量单位(可以看一下上边的表)
               graphics.DrawString("识别成功!\r\n" + content, font, Brushes.Blue, new Point(panel3.Width / 2 - 72, 25));//绘制字体,font是上边定义的字体,Brushes.Brown是颜色,Point是字从哪个位置开始绘制
          
               Brush b = new SolidBrush(Color.Red);//声明的画刷

               int margin = 20;
               int tempx = Convert.ToInt32(x * 1.0 / map.Width * (panel3.Width - 2 * margin) + margin);
               int tempy = Convert.ToInt32(y * 1.0 / map.Height * (panel3.Height - 2 * margin) + margin);
               graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;//平滑绘制
               graphics.FillEllipse(b, new Rectangle(tempx-5,tempy-5, 10,10));             
               graphics.Dispose();
           }
           else
           {
               MessageBox.Show("识别失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
           }
        }

发布了163 篇原创文章 · 获赞 264 · 访问量 107万+

猜你喜欢

转载自blog.csdn.net/u011555996/article/details/103840938
今日推荐