打靶识别(Opencv For Unity惊现bug)

    在使用opencv for unity做图像处理的时候突然出现bug,就是读取工程目录下的图片时会无法读到图像,我使用的是Imgcodecs.imread(imgpath, 1),这一句语句来读图像,但发现读的图像都为空,百思不得其姐,然后偶然发现使用绝对路径的话就能够正常读取,读取一次之后再使用工程路径来读图像就没问题,我用的unity版本是5.6.1f1,opencv for unity版本是2.2.8,算是踩了个坑吧。。。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//opencv图像处理库
using OpenCVForUnity;
using System;

public class top : MonoBehaviour {
    //左边图像UI对象,用于点击切换图像
    public Image icon;

    //图像路径文本
    public UnityEngine.UI.Text path;
    //打靶分数,一共十个
    public UnityEngine.UI.Text[] result = new UnityEngine.UI.Text[10];

    //总环数
    public UnityEngine.UI.Text grade;
    //平均环数
    public UnityEngine.UI.Text mean_grade;
    //剩余子弹数量
    public UnityEngine.UI.Text bull;

    //是否点击button
    bool isplay = false;

    //载入图像的载体
    Texture2D imshow;
    //对图像进行缩放
    Size image_size = new Size(512, 512);
    //红色画笔
    Scalar color = new Scalar(255, 0, 0);
    //中心靶坐标
    Point point = new Point(260, 297);
    //每一环离中心的位置
    double dis = 48f;
    // Use this for initialization
    void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
    
	}

    //点击button的触发函数
    public void top_button()
    {
        //控制点击的开关,不写也行,职业病。
        if (!isplay)
            isplay = true;
        else
            isplay = false;
        //职业病
        if (isplay)
        {
            //获取图像路径
            string imgpath = path.text;
            //原画读取图像
            Mat imgMat = Imgcodecs.imread(imgpath, 1);
            //将图像按比例缩小到512,512
            Imgproc.resize(imgMat, imgMat, image_size);
            //创建一个灰度图的载体
            Mat grayMat = new Mat();
            //将图像转成灰度图
            Imgproc.cvtColor(imgMat, grayMat, Imgproc.COLOR_RGB2GRAY);
            //图像宽高,其实都是512,但是职业病。
            int h = grayMat.rows();
            int w = grayMat.cols();
            //遍历图像像素点坐标x,y
            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < w; j++)
                {
                    //获取图像的像素值,灰度图值范围为0-255
                    int pixe = (int)grayMat.get(i, j)[0];
                    //判断值,如果接近黑色,将像素值修改为白色
                    if (pixe < 15)
                    {
                        grayMat.put(i, j, 255f);
                    }
                    //否则设置为黑色
                    else
                    {
                        grayMat.put(i, j, 0f);
                    }
                    //因为图片集上打击位置为黑色,所以将黑色设置为目标白色信息
                    //其余为不需要的信息设置为黑色去除掉
                }
            }
            //
            //创建集合来保存弹孔位置的轮廓
            List<MatOfPoint> imgContours = new List<MatOfPoint>();
            //轮廓信息
            Mat hieMat = new Mat();
            //寻找图像轮廓
            Imgproc.findContours(grayMat, imgContours, hieMat, 0, 2);
            //用10减去轮廓数量为剩余子弹,放到text上显示出来
            bull.text = (10 - imgContours.Count).ToString();
            //定义一个总环数
            double all = 0f;
            //遍历轮廓(即每个弹孔)
            for (int i = 0; i < imgContours.Count; i++)
            {
                //定义一个空坐标用于存放坐标位置
                Point point_grade = new Point();
                //弹孔半径
                float[] radius = new float[1];
                //在图像上给弹孔位置画上红色
                Imgproc.drawContours(imgMat, imgContours, i, color, 2);
                //获取弹孔位置
                Imgproc.minEnclosingCircle(new MatOfPoint2f(imgContours[i].toArray()), point_grade, radius);
                //给弹孔画上编号
                Imgproc.putText(imgMat, (i+1).ToString(), new Point(point_grade.x - 20, point_grade.y - 20), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(255, 0, 0), 2, Imgproc.LINE_AA, false);
                //通过公式c~2 = a~2 + b~2,求弹孔与靶心距离
                double dis_bull = Math.Sqrt(Math.Pow(Math.Abs(point_grade.x - point.x), 2) + Math.Pow(Math.Abs(point_grade.y - point.y), 2));
                //成绩为10 - 距离除以环宽 + 1
                double grade_result = 10f - (dis_bull / dis) + 1;
                //给相应的textUI写上分数
                result[i].text = grade_result.ToString("f2");
                //累加分数
                all += grade_result;
                //E:/bbb/look1.jpg
            }
            //打印总分数
            grade.text = all.ToString("f2");
            //总分数除以子弹孔数为平均分数
            mean_grade.text = (all / imgContours.Count).ToString("f2");
            //定义一个贴图对象
            imshow = new Texture2D(imgMat.cols(), imgMat.rows());
            //将opencv读取的Mat对象转成贴图类型
            Utils.matToTexture2D(imgMat, imshow);
            //定义一个画布,将贴图内容放上去
            Sprite s = Sprite.Create(imshow, new UnityEngine.Rect(0, 0, imshow.width, imshow.height), Vector2.zero);
            //显示读取的图像
            icon.sprite = s;
            //职业病
            isplay = false;
        }
    }
}

 

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值