精华内容
下载资源
问答
  • OpenCV简单标准数字识别

    万次阅读 多人点赞 2018-10-21 15:32:22
    在学习openCV时,看到一个问答做数字识别,里面配有代码,应用到了openCV里面的ml包,很有学习价值。 https://stackoverflow.com/questions/9413216/simple-digit-recognition-ocr-in-opencv-python# import sys ...

    在学习openCV时,看到一个问答做数字识别,里面配有代码,应用到了openCV里面的ml包,很有学习价值。

    https://stackoverflow.com/questions/9413216/simple-digit-recognition-ocr-in-opencv-python#

    import sys
    import numpy as np
    import cv2
     
    im = cv2.imread('t.png')
    im3 = im.copy()
     
    gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)   #先转换为灰度图才能够使用图像阈值化
    
    thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)  #自适应阈值化
    
    ##################      Now finding Contours         ###################
    # 
    image,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    #边缘查找,找到数字框,但存在误判
     
    samples =  np.empty((0,900))    #将每一个识别到的数字所有像素点作为特征,储存到一个30*30的矩阵内
    responses = []                  #label
    keys = [i for i in range(48,58)]    #48-58为ASCII码
    count =0
    for cnt in contours:
        if cv2.contourArea(cnt)>80:     #使用边缘面积过滤较小边缘框
            [x,y,w,h] = cv2.boundingRect(cnt)   
            if  h>25 and h < 30:        #使用高过滤小框和大框
                count+=1
                cv2.rectangle(im,(x,y),(x+w,y+h),(0,0,255),2)
                roi = thresh[y:y+h,x:x+w]
                roismall = cv2.resize(roi,(30,30))
                cv2.imshow('norm',im)
                key = cv2.waitKey(0)
                if key == 27:  # (escape to quit)
                    sys.exit()
                elif key in keys:
                    responses.append(int(chr(key)))
                    sample = roismall.reshape((1,900))
                    samples = np.append(samples,sample,0)
                if count == 100:        #过滤一下过多边缘框,后期可能会尝试极大抑制
                    break
    responses = np.array(responses,np.float32)
    responses = responses.reshape((responses.size,1))
    print ("training complete")
     
    np.savetxt('generalsamples.data',samples)
    np.savetxt('generalresponses.data',responses)
    #
    cv2.waitKey()
    cv2.destroyAllWindows()

    训练数据为:

    测试数据为:

    使用openCV自带的ML包,KNearest算法

    
    import sys
    import cv2
    import numpy as np
    
     #######   training part    ############### 
    samples = np.loadtxt('generalsamples.data',np.float32)
    responses = np.loadtxt('generalresponses.data',np.float32)
    responses = responses.reshape((responses.size,1))
     
    model = cv2.ml.KNearest_create()
    model.train(samples,cv2.ml.ROW_SAMPLE,responses)
    
    
    def getNum(path):
        im = cv2.imread(path)
        out = np.zeros(im.shape,np.uint8)
        gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
        
        #预处理一下
        for i in range(gray.__len__()):
            for j in range(gray[0].__len__()):
                if gray[i][j] == 0:
                    gray[i][j] == 255
                else:
                    gray[i][j] == 0
        thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)
         
        image,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
        count = 0 
        numbers = []
        for cnt in contours:
            if cv2.contourArea(cnt)>80:
                [x,y,w,h] = cv2.boundingRect(cnt)
                if  h>25:
                    cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
                    roi = thresh[y:y+h,x:x+w]
                    roismall = cv2.resize(roi,(30,30))
                    roismall = roismall.reshape((1,900))
                    roismall = np.float32(roismall)
                    retval, results, neigh_resp, dists = model.findNearest(roismall, k = 1)
                    string = str(int((results[0][0])))
                    numbers.append(int((results[0][0])))
                    cv2.putText(out,string,(x,y+h),0,1,(0,255,0))
                    count += 1
            if count == 10:
                break
        return numbers
    
    numbers = getNum('1.png')

     

    展开全文
  • opencv测试的基本代码

    2021-01-20 23:29:51
    开始一直运行不正确,发现和标准代码有出入。发现是使用img.empty() == 0这个用法是错误的。 #include <opencv2/core.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #...

    开始一直运行不正确,发现和标准代码有出入。发现是使用img.empty() == 0这个用法是错误的。

    #include <opencv2/core.hpp>
    #include <opencv2/imgcodecs.hpp>
    #include <opencv2/highgui.hpp>
    #include <opencv2/opencv.hpp>
    #include "opencv2/highgui/highgui.hpp"
    #include <iostream>
    
    // using namespace std;
    using namespace cv;
    
    int main()
    {
    	std::string path = "basketBall.jpg";
    	Mat img = imread(path,IMREAD_COLOR);
    	// Mat img = imread("basketBall.jpg",IMREAD_COLOR);
    	if (img.empty())
    	{
    		std::cout << "打开图像失败!" <<std::endl;
    		return -1;
    	}
    	namedWindow("image", CV_WINDOW_AUTOSIZE);
    	cv::imshow("image", img);
    	waitKey();
    
    	return 0;
    }
    

    empty()函数提示

    bool cv::Mat::empty() const
    Returns true if the array has no elements. The method returns true if Mat::total() is 0 or if Mat::data is NULL. Because of pop_back() and resize() methods M.total() == 0 does not imply that M.data == NULL.

    官方给出的样例

    #include <opencv2/core.hpp>
    #include <opencv2/imgcodecs.hpp>
    #include <opencv2/highgui.hpp>
    #include <iostream>
    using namespace cv;
    int main()
    {
        std::string image_path = samples::findFile("basketBall.jpg");
        Mat img = imread(image_path, IMREAD_COLOR);
        if(img.empty())
        {
            std::cout << "Could not read the image: " << image_path << std::endl;
            return 1;
        }
        imshow("Display window", img);
        int k = waitKey(0); // Wait for a keystroke in the window
        if(k == 's')
        {
            imwrite("starry_night.png", img);
        }
        return 0;
    }
    
    展开全文
  • opencv测试程序

    2014-03-04 22:33:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    int main(int argc, char** argv)
    {
    	cv::Mat mat=cv::imread("c:\lena.jpg");
    	cv::namedWindow("lena");
    	cv::imshow("lena",mat);
    	cv::waitKey(0);
    	return 0;
    }


    转载于:https://my.oschina.net/gujianhan/blog/205200

    展开全文
  • OpenCV

    2019-08-14 15:07:00
    OpencvForUnity 插件的文档 :https://enoxsoftware.github.io/OpenCVForUnity/3.0.0/doc/html/annotated.html OpenCVSharp : https://github.com/shimat/opencvsharp OpenCVSharp 文档:...

    OpencvForUnity 插件的文档  :https://enoxsoftware.github.io/OpenCVForUnity/3.0.0/doc/html/annotated.html

    OpenCVSharp :    https://github.com/shimat/opencvsharp

    OpenCVSharp 文档: https://shimat.github.io/opencvsharp_docs/html/47b728ac-aff3-f998-4902-42d117710f4d.htm#!

    如果没使用Nuget则获取DLL文件的方式,https://github.com/shimat/opencvsharp/releases

    找dll库网:https://www.zhaodll.com/dll/softdown.asp?iz2=8aeff38ef164ad5eda73195ddb24ff96&softid=340814

    OpenCV  EmguCV :  https://www.jianshu.com/p/8a24b593c83a 

    EmguCV在unity上的部署:    https://forum.unity.com/threads/opencv-emgucv-wrapper-integration-in-unity.182600/

    Dll库: https://www.pconlife.com/viewfileinfo/opencv-core249-dll/

    opencv: 下载链接 https://opencv.org/releases/page/4/   https://www.cnblogs.com/icyhoo/p/6474053.html

    opencv2.4文档:   https://docs.opencv.org/2.4/modules/core/doc/old_basic_structures.html?highlight=iplimage#IplImage

    查看.net库的.dll是多少位:

    1. 下载Reflector

    2. 打开

    3. 输入指令

    4. 会打开Reflector

     

    Unity 导入.net架构高于Unity的dll时,则会引发编译错误:

     

     

    Unity Native Plugins:

    导入或者卸载后需要重新启动Unity.

     

    Unity使用OpencvSharp :

    方式一: 

    https://blog.csdn.net/vincentff7zg/article/details/54691783  //创建流程

    https://www.bbsmax.com/A/Gkz10WEgdR/  //可能存在的问题解决方案

    https://www.bbsmax.com/A/mo5kl3AKdw/    //可能存在的问题解决方案

    <1.需要下载对应版本的opencv;

       链接 https://opencv.org/releases/page/4/ 

       下载安装后,把里面c#需要封装的opencv dll库全部拷到unity plugins中。

        

    <2.需要下载对应版本的OpencvSharp;

         --1. 需要在vs中把下载后的OpencvSharp. 因为下载高版本.net框架太高,在unity里可能不能用。

               

        ---2. 打开源码: 提示是否更新,则选择更新,相当于你用vs2015打开了低版本的工程。会把环境定向到低版本环境中。

                

       ---3.  重新生成这三个的解决方案:

        https://www.youtube.com/watch?v=tUWoKxH3zxw   //youtobe老外生成的教程,他是32位的哦

        由于OpenCvSharpExtern是c++写的,所以我这里重新生成时会出错,因为虽然定向到了低版本,但是重新生成时,需要的低版本的库找不到。所以我只生成了前两个,如果你的可以那就更好。把前两个生成的Debug中dll文件拷贝到Unity plugins中。

             

    ---4.第三个生成方式:新建一个vs工程,使用NuGet包管理器来获取,注意一定要把版本下对。

          

       

    <4. 把生成的dll文件和opencv中对应的dll文件,拷贝到plugins中。应该可以直接从此处把dll文件导入,你们可以试一试

         

     <5. 大功告成:再不报错了

           

     

    方式二:

       <1. 新建一个vs工程,使用NuGet包管理器来获取,注意一定要把版本下对。

          

       

       <2. 应该可以直接从此处把dll文件导入,你们可以试一试

         

    <3. 测试后可以使用,但是有个粗无,找不到一个库. 可以用这种方式比较简单,不容易出错。

          

     

    对使用指针的操作:

     

     

     

    一、没有模板的情况——根据一定规则进行识别

    对于背景不是纯色的图片:

        /// <summary>
        /// 分水岭算法
        /// MatchShapes Example
        /// https://baike.baidu.com/item/%E5%9B%BE%E5%83%8F%E4%BA%8C%E5%80%BC%E5%8C%96/1748870?fr=aladdin
        /// http://docs.opencv.org/3.1.0/d5/d45/tutorial_py_contours_more_functions.html
        /// https://docs.opencv.org/3.1.0/df/d4e/group__imgproc__c.html#ga5c79f8ca95dc7a93f7142b218bea61f3  //文档
        /// https://docs.opencv.org/3.1.0/d7/d1b/group__imgproc__misc.html#gae8a4a146d1ca78c626a53577199e9c57  //文档  threshold
        /// 
        ///  会把背景上的颜色分割出来,对图像轮廓点进行多边形拟合,对比顶点个数 【分水岭算法】  优先使用二值法,不行了再考虑这种方法,这种方法误差较大

     

    using UnityEngine;
    using System.Collections.Generic;
    using UnityEngine.UI;
    using System.Collections;
    
    #if UNITY_5_3 || UNITY_5_3_OR_NEWER
    using UnityEngine.SceneManagement;
    #endif
    using OpenCVForUnity;
    
    namespace OpenCVForUnityExample
    {
        /// <summary>
        /// 分水岭算法
        /// MatchShapes Example
        /// https://baike.baidu.com/item/%E5%9B%BE%E5%83%8F%E4%BA%8C%E5%80%BC%E5%8C%96/1748870?fr=aladdin
        /// http://docs.opencv.org/3.1.0/d5/d45/tutorial_py_contours_more_functions.html
        /// https://docs.opencv.org/3.1.0/df/d4e/group__imgproc__c.html#ga5c79f8ca95dc7a93f7142b218bea61f3  //文档
        /// https://docs.opencv.org/3.1.0/d7/d1b/group__imgproc__misc.html#gae8a4a146d1ca78c626a53577199e9c57  //文档  threshold
        /// https://enoxsoftware.github.io/OpenCVForUnity/3.0.0/doc/html/annotated.html  //这个插件的文档
        ///  会把背景上的颜色分割出来,对图像轮廓点进行多边形拟合,对比顶点个数 【分水岭算法】  优先使用二值法,不行了再考虑这种方法,这种方法误差较大
        /// 
        /// </summary>
        public class test_MatchShapesExample : MonoBehaviour
        {
            public float threshValue = 127;  //阀值
            public float periMin = 200;
            public float periMax = 1000;
            void Update()
            {
                if (Input.GetMouseButtonDown(1))
                {
    
                    //分水岭算法
                    //srcMat
                    Texture2D srcTexture = Resources.Load("matchshapes_Creat_Src") as Texture2D;
                    Mat srcMat = new Mat(srcTexture.height, srcTexture.width, CvType.CV_8UC1);
                    Utils.texture2DToMat(srcTexture, srcMat);
                    Debug.Log("srcMat.ToString() " + srcMat.ToString());
                    Imgproc.threshold(srcMat, srcMat, threshValue, 255, Imgproc.THRESH_OTSU);   
    
                    //dstMat
                    Texture2D dstTexture = Resources.Load("matchshapes_Creat_Src") as Texture2D;
                    Mat dstMat = new Mat(dstTexture.height, dstTexture.width, CvType.CV_8UC3);
                    Utils.texture2DToMat(dstTexture, dstMat);
                    Debug.Log("dstMat.ToString() " + dstMat.ToString());
    
    
                    List<MatOfPoint> srcContours = new List<MatOfPoint>();
                    Mat srcHierarchy = new Mat();
    
                    /// Find srcContours
                    Imgproc.findContours(srcMat, srcContours, srcHierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_NONE);
    
                    Debug.Log("srcContours.Count " + srcContours.Count);
    
                    for (int i = 0; i < srcContours.Count; i++)
                    {
                        Imgproc.drawContours(dstMat, srcContours, i, new Scalar(255, 0, 0), 2, 8, srcHierarchy, 0, new Point());
                    }
    
                    for (int i = 0; i < srcContours.Count; i++)
                    {
                        double returnVal = Imgproc.matchShapes(srcContours[1], srcContours[i], Imgproc.CV_CONTOURS_MATCH_I1, 0);
                        //Debug.Log("returnVal " + i + " " + returnVal);
    
                        MatOfPoint2f newMatOfPoint2f = new MatOfPoint2f(srcContours[i].toArray());
                        //主要是计算图像轮廓的周长
                        double peri = Imgproc.arcLength(newMatOfPoint2f, true);
                        if (peri < periMin || peri > periMax)
                        {
                            continue;
                        }
                        else
                        {
                            //对图像轮廓点进行多边形拟合
                            MatOfPoint2f polyShape = new MatOfPoint2f();
                            Imgproc.approxPolyDP(newMatOfPoint2f, polyShape, 0.04f * peri, true);
                            int shapeLen = polyShape.toArray().Length;
    
                            if (shapeLen >= 3 && shapeLen <= 20)
                            {
                                Debug.LogWarning(shapeLen + "        " + returnVal);
                                OpenCVForUnity.Rect rect = Imgproc.boundingRect(srcContours[i]);
                                float width = rect.width;
                                float height = rect.height;
                                float ar = width / height;
                                //计算宽高比,判断是矩形还是正方形
                                string name = null;
                                if (shapeLen == 3) { name = "triangle"; }
                                else if (shapeLen == 4)
                                {
                                    //计算宽高比,判断是矩形还是正方形
                                    if (ar >= 0.95 && ar <= 1.05) { name = "square"; } else { name = "rectangle"; }
                                }
                                else { name = shapeLen.ToString(); }
    
                                Point point = new Point();
                                float[] radius = new float[1];
                                Imgproc.minEnclosingCircle(new MatOfPoint2f(srcContours[i].toArray()), point, radius);
                                //Debug.Log("point.ToString() " + point.ToString());
                                //Debug.Log("radius.ToString() " + radius[0]);
    
                                Imgproc.circle(dstMat, point, 5, new Scalar(0, 0, 255), -1);
                                Imgproc.putText(dstMat, " " + name, point, Core.FONT_HERSHEY_SIMPLEX, 0.4, new Scalar(0, 255, 0), 1, Imgproc.LINE_AA, false);
                            }
                        }
                    }
                    Texture2D texture = new Texture2D(dstMat.cols(), dstMat.rows(), TextureFormat.RGBA32, false);
                    Utils.matToTexture2D(dstMat, texture);
                    GameObject.Find("pic_RawImage").GetComponent<RawImage>().texture = texture;
                }
            }
    
        }
    }

    对于背景是纯色的图片识别图片中的形状:

                //此图同背景的差别表现不在灰度值上(比如纹理不同),所以将这个差别特征转换为灰度的差别,然后利用阈值选取技术来分割该图像,动态调节阈值实现图像的二值化可动态观察其分割图像的具体结果。
                //一般用在背景是同一种颜色时,如果背景含有多种颜色,则不行  
    using OpenCVForUnity;
    using OpenCVForUnityExample;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    /// <summary>
    /// https://blog.csdn.net/u013293580/article/details/84710933#commentsedit
    /// </summary>
    public class shapeDectedScript : MonoBehaviour {
    
        public RawImage color_Pic; //UI
        private Mat srcMat; //Mat格式存放处理的图片
    
        public float size=5;
        public float threshValue = 80;  //阀值
        private Mat dstMat; //Mat格式存放处理的图片
        private Texture2D flipTexture;
        public List<ShapeInfo> listShape=new List<ShapeInfo>(); 
    
        private void Update()
        {
                if (Input.GetMouseButtonDown(1))
            {
    
    
                System.Diagnostics.Stopwatch oTime = new System.Diagnostics.Stopwatch();   //定义一个计时对象  
                oTime.Start();
    
    
                listShape.Clear();
                Texture2D tex = (Texture2D)GameObject.Find("Quad").GetComponent<MeshRenderer>().materials[0].mainTexture;
                Texture2D flipTexture = new Texture2D(tex.width, tex.height);
                for (int i = 0; i < tex.height; i++)
                {
                    flipTexture.SetPixels(0, i, tex.width, 1, tex.GetPixels(0, tex.height - i - 1, tex.width, 1));
                }
                flipTexture.Apply();
    
    
    
                //此图同背景的差别表现不在灰度值上(比如纹理不同),所以将这个差别特征转换为灰度的差别,然后利用阈值选取技术来分割该图像,动态调节阈值实现图像的二值化可动态观察其分割图像的具体结果。
                //一般用在背景是同一种颜色时,如果背景含有多种颜色,则不行  
    
                srcMat = new Mat(flipTexture.height, flipTexture.width, CvType.CV_8UC1);
                Utils.texture2DToMat(flipTexture, srcMat);
    
                //读取图片   参照图   白色线
               // srcMat = Imgcodecs.imread(Application.dataPath + "/Resources/matchshapes_Creat_Test.png", 1);
                //图片颜色模式转换,转为灰度图
                Imgproc.cvtColor(srcMat, srcMat, Imgproc.COLOR_BGR2GRAY);
                //图片高斯模糊处理   
                Imgproc.GaussianBlur(srcMat, srcMat, new Size(size, size), 0);   // 使得内部有均匀一致的灰度值,而且此图片的背景是在其他等级灰度值的均匀背景
                //图片二值化处理   特征转换为灰度的差别,再利用阀值进行分离背景
                Imgproc.threshold(srcMat, srcMat, threshValue, 255, Imgproc.THRESH_BINARY);  //图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值.
    
    
    
    
    
    
                dstMat = new Mat(flipTexture.height, flipTexture.width, CvType.CV_8UC1);
                Utils.texture2DToMat(flipTexture, dstMat);
                //读取新图片
                //dstMat =Imgcodecs.imread(Application.dataPath + "/Resources/matchshapes_Creat_Test.png", 1);
                //Imgproc.COLOR_BGR2RGB的颜色模式可以让图片保持原色
                Imgproc.cvtColor(dstMat, dstMat, Imgproc.COLOR_BGR2RGB);
                //对新图片何原图片进行对比
                List<MatOfPoint> srcContours = new List<MatOfPoint>();
                Mat srcHierarchy = new Mat();
                //寻找轮廓
                Imgproc.findContours(srcMat, srcContours, srcHierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_NONE);
                for (int i = 0; i < srcContours.Count; i++)
                {
                    //轮廓描边
                    //Imgproc.drawContours(dstMat, srcContours, i, new Scalar(255, 0, 0), 2, 8, srcHierarchy, 0, new Point());
                    Point point = new Point();
                    float[] radius = new float[1];
                    //获取点集最小外接圆点
                    Imgproc.minEnclosingCircle(new MatOfPoint2f(srcContours[i].toArray()), point, radius);
                    //在圆点位置绘制圆形
                    Imgproc.circle(dstMat, point, 7, new Scalar(255, 255, 0), -1);
                    MatOfPoint2f newMatOfPoint2f = new MatOfPoint2f(srcContours[i].toArray());
                    enDetectShape enShape = detect(srcContours[i], newMatOfPoint2f);
                    //在图形圆心的(20,20)的右上方会绘制该轮廓的名字
                    Imgproc.putText(dstMat, enShape.ToString(), new Point(point.x - 20, point.y - 20), Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(255, 0, 0), 2, Imgproc.LINE_AA, false);
    
                    if (enShape != enDetectShape.Null)
                    {
                        ShapeInfo shapeInfo = new ShapeInfo();
                        shapeInfo.point = new Vector2((float)point.x, tex.height - (float)point.y);
                        shapeInfo.enShape = enShape;
                        listShape.Add(shapeInfo);
                    }
                    
                }
    
    
                //定义Texture2D设置其宽高随scrMat材质颜色模式为RGBA32
                 texture = new Texture2D(dstMat.cols(), dstMat.rows(), TextureFormat.RGBA32, false);
                //把Mat格式转换成texture格式
                Utils.matToTexture2D(dstMat, texture);
                //把texture贴在UI RawImage上
    
                color_Pic.texture = texture;
                color_Pic.material.mainTexture= texture;
    
                oTime.Stop();  
                Debug.LogError("程序的运行时间:{0} 秒" + "   " + oTime.Elapsed.TotalSeconds);
                Debug.LogError("程序的运行时间:{0} 毫秒" + "    " + oTime.Elapsed.TotalMilliseconds);
            }
    
    
        }  
       //圆和星星的判断   https://blog.51cto.com/xvjunjie/2416635?source=dra
        //在检测时发现有时候圆和星星有可能被误识别,通过获取轮廓上第一个点和图形的中心点。计算两点的距离,使用圆的面积公式求面积。
        //在使用OpenCV3.3中自带的轮廓区域面积函数获取面积。通过比较来判断是圆形还是星星,因为同等距离的星星的面积比圆小。
        public Texture2D test;
        public Texture2D texture;
        public enDetectShape detect(MatOfPoint mp, MatOfPoint2f mp2f)
        {
            enDetectShape enShape = enDetectShape.Null;
            //主要是计算图像轮廓的周长
            double peri = Imgproc.arcLength(mp2f, true);
          
            //对图像轮廓点进行多边形拟合
            MatOfPoint2f polyShape = new MatOfPoint2f();
            Imgproc.approxPolyDP(mp2f, polyShape, 0.04f * peri, true);
            int shapeLen = polyShape.toArray().Length;
            Debug.Log(shapeLen);
            //根据轮廓凸点拟合结果,判断属于那个形状
            switch (shapeLen)
            {
                case 3:
                    enShape = enDetectShape.Null;
                    break;
                case 4:
                    OpenCVForUnity.Rect rect = Imgproc.boundingRect(mp);
                    float width = rect.width;
                    float height = rect.height;
                    float ar = width / height;
                    //计算宽高比,判断是矩形还是正方形
                    if (ar >= 0.95 && ar <= 1.05)
                    {
                        enShape = enDetectShape.Square;
                    }
                    else
                    {
                        enShape = enDetectShape.Rectangle;  
                    }
                    break;
                case 5:
                    enShape = enDetectShape.Pentagon;
                    break;
                default:
                    enShape = enDetectShape.Circle; 
                    break;
            }
            return enShape;
        }
    }
    
    public class ShapeInfo
    {
        public Vector3 point;
        public enDetectShape enShape;
    }
    
    public enum enDetectShape
    {
        Null,
        Triangle,
        Square,
        Rectangle,
        Pentagon,
        Circle,
    }
    

    注意:该图片翻转是 由于direct是左上和opengl是左下坐标的问题。

     

    二、有模板图片——比较图片中形状的相似度

    https://blog.csdn.net/zhuason/article/details/78933250

    1.输入图像

    <1. Mat存在各种类型,maketype()  函数可以返回该Mat的类型。类型表示了材质中元素的类型以及材质的通道个数.

    CvType:
        CvType.CV_8UC4是8位无符号四通道带透明色RGB图像,每一个像素在内存空间占的空间大小是8位。
        CvType.CV_8UC1是 1通道(单通道) 
    
        CV_CN_SHIFT = 3;
        CV_DEPTH_MAX = (1 << CV_CN_SHIFT);   //= 1*2^3=8
        //前半句 :  把深度编号和(8-1)进行与运算  +    后半句:  (channels - 1)*2^3       
        //与运算目的:取某数中指定位   即:类型 = 数据类型的编号 + (通道数 - 1) * 8
        公式:  (depth & (CV_DEPTH_MAX - 1)) + ((channels - 1) << CV_CN_SHIFT);  
    
        Mat M(3,2,CV_8SC3,Scalar(0,0,4));
        cout<<"M="<<M<<endl;
    
    
        创造了一个行数(高度)是3,列数(宽度)是2的图像,图像的type是CV_8SC3,表示图像的元素是8位无符        号整数,3个通道,图像所有的元素都被初始化位(0,0,255),由于opencv颜色的顺序是BGR,所以这张图片是全红色。
        常用的构造函数经常涉及到类型 type。type 可以是 CV_8UC1,CV_16SC1,…, CV_64FC4 等。里面的 8U 表示 8 位无符号整数,16S 表示 16 位有符号整数,64F 表示 64 位浮点数(即 double 类型);C 后面的数表示通道数,例如 C1 表示一个 通道的图像,C4 表示 4 个通道的图像,以此类推。如果为表明通道数,则为如果你需要更多的通道数,需要用宏 CV_8UC(n),例如:Mat M(3,2, CV_8UC(5))
    Mat中重定义了<<操作符,可以直接输出所有像素值

    Imgproc.cs: 图片处理类

     Imgproc.GaussianBlur;

    c#和c++之间的问题:

    .net3.0   intptr和int类型不能相加;  再.net4.0才可以相加。所以要把intptr类型转换为int32()类型。

     

    一:感知哈希算法

    <根据图像的明暗信息,对每张图片生成一个"指纹"(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。

    第一步,缩小尺寸。

    将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。

     

    第二步,简化色彩。

    将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。

    第三步,计算平均值。

    计算所有64个像素的灰度平均值。

    第四步,比较像素的灰度。

    将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。因为图片相似度和颜色关系不大

    第五步,计算哈希值。

    方差: 在概率论和统计方差衡量随机变量或一组数据时离散程度的度量。概率论中方差用来度量随机变量和其数学期望(即均值)之间的偏离程度

    将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。

    汉明距离: (Hamming distance,在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数)

     =  = 8f373714acfcf4d0

    //链接  https://blog.csdn.net/wangyaninglm/article/details/43853435#_935

    //链接 https://blog.csdn.net/haofan_/article/details/78806143

    
        //图像大小(会压缩)   颜色区域分布在同一 块的比例  
        int size2 = 512;
        //截取所画区域的图
        //根据灰度直方图来比较
        //hash 参考链接  https://blog.csdn.net/wangyaninglm/article/details/43853435
        //opencv doc https://docs.opencv.org/master/da/d54/group__imgproc__transform.html#gga5bb5a1fea74ea38e1a5445ca803ff121aa5521d8e080972c762467c45f3b70e6c
        //opencv doc of old version https://docs.opencv.org/2.4/modules/gpu/doc/image_processing.html?highlight=inter_nearest
        unsafe void Fun3()
        {
            Mat matSrc=new Mat(), matSrc1=new Mat(), matSrc2=new Mat(),  matSrc4 = new Mat();
            matSrc = Cv2.ImRead(Application.dataPath + "/Resources/YaoM2.png", LoadMode.Color);
            matSrc4 = Cv2.ImRead(Application.dataPath + "/Resources/YaoM3.png", LoadMode.Color);
    
            if (matSrc.Channels() != 3) { Debug.LogError("error  " + matSrc.Channels()); return; }
            //Cv2.Resize(matSrc, matSrc1, Cv.Size(size2, size2), 0, 0, Interpolation.Cubic);
            if (matSrc4.Channels() != 3) { Debug.LogError("error  " + matSrc4.Channels()); return; }
            //Cv2.Resize(matSrc4, matSrc2, Cv.Size(size2, size2), 0, 0, Interpolation.Cubic);
       
    
    
            Mat matDst1 =new Mat(), matDst2=new Mat();
            //Cv2.Resize(matSrc1, matDst1, Cv.Size(8, 8), 0, 0, Interpolation.Cubic);  
            //Cv2.Resize(matSrc2, matDst2, Cv.Size(8, 8), 0, 0, Interpolation.Cubic);
            Cv2.Resize(matSrc, matDst1, Cv.Size(16, 16), 0, 0, Interpolation.Cubic);
            Cv2.Resize(matSrc4, matDst2, Cv.Size(16, 16), 0, 0, Interpolation.Cubic);
    
    
            //灰度,因为图片相似度和颜色关系不大
            //Mat temp1 = matDst1;
            //Mat temp2 = matDst2;
            Cv2.CvtColor(matDst1, matDst1, ColorConversion.BgrToGray);
            Cv2.CvtColor(matDst2, matDst2, ColorConversion.BgrToGray);
    
            //与传统的哈希算法不同:分别依次计算图像每行像素点的平均值,记录每行像素点的平均值。每一个平均值对应着一行的特征。
            //方差是在概率论和统计方差衡量随机变量或一组数据时离散程度的度量。概率论中方差用来度量随机变量和其数学期望(即均值)之间的偏离程度
            int iAvg1 = 0, iAvg2 = 0;
            int[] arr1=new int[size2], arr2=new int[size2];
            for (int i = 0; i < 8; i++)
            {
                char* data1 =(char*) matDst1.Ptr(i);
                char* data2 = (char*)matDst2.Ptr(i);
                int tmp = i * 8;
    
                for (int j = 0; j < 8; j++)
                {
                    int tmp1 = tmp + j;
    
                    arr1[tmp1] =   data1[j] / 4 * 4;
                    arr2[tmp1] = data2[j] / 4 * 4;
    
                    iAvg1 += arr1[tmp1];
                    iAvg2 += arr2[tmp1];
                }
            }
    
            iAvg1 /= size2;
            iAvg2 /= size2;
    
            for (int i = 0; i < size2; i++)
            {
                arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;
                arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0;
            }
            Compare(arr1, arr2);
        }
    
        void Compare(int[] arr1, int[] arr2)
        {
            char[] resStr = new char[size2];
            int iDiffNum = 0;
    
            for (int i = 0; i < size2; i++)
            {
                if (arr1[i] != arr2[i])
                {
                    resStr[i] = '0';
                }
                else
                {
                    ++iDiffNum;
                    resStr[i] = '1';
                }
            }
    
            StringBuilder strBuild = new StringBuilder();
            strBuild.Append(resStr);
    
            //模糊逻辑
            Debug.Log("iDiffNum = " + iDiffNum);
            double value =(double)iDiffNum/ (double)size2;
            Debug.LogWarning(strBuild + "   " + value*100+ "%");
    
    
            //if (iDiffNum <= 5)
            //    Debug.Log(" two images are very similar!");
            //else if((iDiffNum <= 10)&& iDiffNum>5)
            //    Debug.Log("two image are somewhat similar!");
            //else if (iDiffNum > 10)
            //    Debug.Log("they are two different images!");
        }

    二、直方图颜色法;

    http://www.ruanyifeng.com/blog/2013/03/similar_image_search_part_ii.html

    根据颜色生成直方图,如果颜色很接近,就说明是同一张图。

    有点: 计算量适中。比较适合描述难以自动分割的图像。

    缺点:直方图反应的是图像灰度值/ 颜色值得概率分布,并没有图像的空间位置信息在里面,因此,常常出现误判;从信息论来讲,通过直方图转换,信息丢失量较大,因此单一的通过直方图进行匹配显得有点力不从心。

    三、图像模板匹配   

    如果源图像与模板图像尺寸不一样,通常需要进行滑动模板去匹配窗口,扫面个整幅图像获得最好的匹配patch。

    在OpenCV中对应的函数为:matchTemplate():函数功能是在输入图像中滑动窗口寻找各个位置与模板图像patch的相似度。一般适合在同一张图像上抠出来的部分与这个图像匹配。

    下图:

    <1. 模板必须 宽和高都小于源图像,模板缩小后会对图像压缩,框出来的图像就是压缩后的框的位置,如果图片有压缩了,则会框错位置.  绿色框是把的尺寸是使用模板的大小在输入源图中框出来。所以要把模板的尺寸设置的刚刚好。

    <2.所以模板必须是单个图像,否则没法区分。左侧是模板的图片,里面有两个图形。右侧是输入源图。

    <3. 绿色框是把的尺寸是使用模板的大小在输入源图中框出来。所以要把模板的尺寸设置的刚刚好,然后在源图中框出来。

        //模板必须不大于源映像,模板缩小后会对图像压缩,框出来的图像就是压缩后的框的位置,如果图片有压缩了,则会框错位置。

     void setUpTemplate()
        {
            Mat img, templ, result=new Mat();
            //img = imread("nba.jpg");
            //templ = imread("76.png");
    
    
            img = Cv2.ImRead(Application.dataPath + "/Resources/999.png");
            templ = Cv2.ImRead(Application.dataPath + "/Resources/san_2.png");
    
            int result_cols = img.Cols - templ.Cols + 1;
            int result_rows = img.Rows - templ.Rows + 1;
            result.Create(result_cols, result_rows, MatType.CV_32FC1);
            Cv2.MatchTemplate(img, templ, result, MatchTemplateMethod.SqDiffNormed);
            //matchTemplate(img, templ, result, CV_TM_SQDIFF_NORMED);//这里我们使用的匹配算法是标准平方差匹配 method=CV_TM_SQDIFF_NORMED,数值越小匹配度越好   匹配结果存储在result单通道矩阵中
            Cv2.Normalize(result, result, 0, 1,NormType.MinMax, -1,new Mat());
                //normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());
    
            double minVal = -1;
            double maxVal;
            Point minLoc;
            Point maxLoc;
            CvPoint matchLoc;
            Debug.Log ( "匹配度:" +minVal +"   ");
            Cv2.MinMaxLoc(result,out minVal, out maxVal, out minLoc, out maxLoc,new  Mat());
            //minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
    
    
            Debug.Log("匹配度:" + minVal);
    
            matchLoc = minLoc;
            CvScalar color = new CvScalar(0, 255, 0);
            //(CvArr img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness, LineType lineType, int shift);
            CvPoint cvPoint = Cv.Point(matchLoc.X + templ.Cols, matchLoc.Y + templ.Rows);
            LineType LINE = LineType.Link8;
            Cv2.Rectangle(img, matchLoc, cvPoint, color, 2 ,LineType.Link8, 0);
    
            //Cv.Rectangle(img, matchLoc, cvPoint, color, 2, LineType.Link8,0);
            //rectangle (img, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar(0, 255, 0), 2, 8, 0);
    
            Cv2.ImShow("img", img);
            Cv2.WaitKey(0);
        }
    

    检测动物:

    模板法:

    把犀牛检测成了河马:

    特征法:根据独有的特征检测。可以检测出

    //unityforopencv   
     public RawImage image1;
            public RawImage image2;
            public RawImage image3;
            void Start ()
            {
                //from mat1 match to mat2
                Texture2D imgTexture = Resources.Load ("Animator3") as Texture2D;
                
                Mat img1Mat = new Mat (imgTexture.height, imgTexture.width, CvType.CV_8UC3);
                Utils.texture2DToMat (imgTexture, img1Mat);
              
    
                Texture2D imgTexture2 = Resources.Load("Animator") as Texture2D;
                Mat img2Mat = new Mat (imgTexture2.height, imgTexture2.width, CvType.CV_8UC3);
                Utils.texture2DToMat (imgTexture2, img2Mat);
             
    
                //float angle = UnityEngine.Random.Range (0, 360), scale = 1.0f;
                //angle = 0;
                //Point center = new Point (img2Mat.cols () * 0.5f, img2Mat.rows () * 0.5f);
                //Mat affine_matrix = Imgproc.getRotationMatrix2D (center, angle, scale);
                //Imgproc.warpAffine (img1Mat, img2Mat, affine_matrix, img2Mat.size ());
    
    
                ORB detector = ORB.create ();
                ORB extractor = ORB.create ();
    
                MatOfKeyPoint keypoints1 = new MatOfKeyPoint ();
                Mat descriptors1 = new Mat ();
                detector.detect (img1Mat, keypoints1);
                extractor.compute (img1Mat, keypoints1, descriptors1);
                Texture2D texture1 = new Texture2D(img1Mat.cols(), img1Mat.rows(), TextureFormat.RGBA32, false);
                Utils.matToTexture2D(img1Mat, texture1);
                //image1.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, (float)img1Mat.width());
                //image1.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, (float)img1Mat.height());
                image1.texture = texture1;
    
                MatOfKeyPoint keypoints2 = new MatOfKeyPoint ();
                Mat descriptors2 = new Mat ();
                detector.detect (img2Mat, keypoints2);
                extractor.compute (img2Mat, keypoints2, descriptors2);
                Texture2D texture2 = new Texture2D(img2Mat.cols(), img2Mat.rows(), TextureFormat.RGBA32, false);
                Utils.matToTexture2D(img2Mat, texture2);
                image2.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, (float)img2Mat.width());
                image2.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, (float)img2Mat.height());
                image2.texture = texture2;
    
    
    
                DescriptorMatcher matcher = DescriptorMatcher.create (DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);//BRUTEFORCE_HAMMINGLUT
                MatOfDMatch matches = new MatOfDMatch ();
                matcher.match (descriptors1, descriptors2, matches);
    
                
                Mat resultImg = new Mat ();
                Features2d.drawMatches (img1Mat, keypoints1, img2Mat, keypoints2, matches, resultImg);
                Texture2D texture = new Texture2D (resultImg.cols (), resultImg.rows (), TextureFormat.RGBA32, false);
                Utils.matToTexture2D (resultImg, texture);
    
                image2.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, (float)img2Mat.width());
                image2.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, (float)img2Mat.height());
                image2.texture = texture2;
    
                gameObject.GetComponent<Renderer> ().material.mainTexture = texture;
            }

    https://www.youtube.com/watch?v=bUrjFGMfwas

    总结:hash和模板匹配都只对自身截图的匹配比较好,对自己手动画的匹配效果不好。

     

     

    网友提出的一种新方法:

    二值化 --->找出角点-->旋转--->寻找特征点

    一、角点(corner)

            https://blog.csdn.net/zhu_hongji/article/details/81235643
           角点通常被定义为两条边的交点,或者说,角点的局部邻域应该具有两个不同区域的不同方向的边界。角点检测(Corner Detection)是计算机视觉系统中获取图像特征的一种方法,广泛应用于运动检测、图像匹配、视频跟踪、三维重建和目标识别等,也可称为特征点检测。

    1、角点的类型

      使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。

      目前,角点检测算法还不是十分完善,许多算法需要依赖大量的训练集和冗余数据来防止和减少错误的特征的出现。对于角点检测算法的重要评价标准是:其对多幅图像中相同或者相似特征的检测能力,并且能够应对光照变化、或者图像旋转等影响。

    • 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
    • 两条及两条以上边缘的交点;
    • 图像中梯度值和梯度方向的变化速率都很高的点; 
    • 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。   
    • 三类角点检测算法:

      基于二值图像的角点检测;
      基于轮廓曲线的角点检测;
      基于灰度图像的角点检测:基于梯度、基于模板和基于模板和梯度组合三类方法;常见的基于模板的角点检测算法有:Kitchen-Rosenfeld角点检测算法,Harris角点检测算法,KLT角点检测算法及SUSAN角点检测算法。基于模板的方法主要是考虑像素领域点灰度的变化,即亮度的变化。

      1、Harris角点检测 
      1.1 原理分析

      1.1.1 算法思想

              角点原理来源于人对角点的感性判断,即图像在各个方向灰度有明显变化。算法的核心是利用局部窗口在图像上进行移动判断灰度发生较大的变化,所以此窗口用于计算图像的灰度变化为(3*3的窗口,这和计算梯度变化算子一样):[-1,0,1;-1,0,1;-1,0,1][-1,-1,-1;0,0,0;1,1,1]。根据下面三幅图可以清晰理解角点检测的过程:当一个窗口在图像上移动,如图(a),窗口在各个方向上都没有变化,则认为窗口区域为平滑区域。如图(b),窗口在某个方向上没有变化,另一个方向上有明显变化,那么,这块区域可能存在边缘。如图(c),窗口在各个方向上灰度发生了较大的变化,那么,这块区域可能存在角点。Harris角点检测正是利用了这个直观的物理现象,通过窗口在各个方向上的变化程度,决定是否为角点。
       

          

    1.1.2 数学表示

    根据算法思想,构建数学模型,计算移动窗口的的灰度差值。

            

    OpenCV里面的API:

    C++:void cornerHarris( InputArray src, //输入8bit单通道灰度Mat矩阵
                      OutputArray dst, //用于保存Harris角点检测结果,32位单通道,大小与src相同
                      int blockSize,   //滑块窗口的尺寸
                      int ksize,       //Sobel边缘检测滤波器大小
                      double k,        //Harris中间参数,经验值0.04~0.06
                      int borderType=BORDER_DEFAULT  //插值类型

    二、Shi-Tomasi角点检测
            Shi-Tomasi 算法是Harris 算法的改进。Harris 算法最原始的定义是将矩阵 M 的行列式值与 M 的迹相减,再将差值同预先给定的阈值进行比较。后来Shi 和Tomasi 提出改进的方法,若两个特征值中较小的一个大于最小阈值,则会得到强角点。
    Shi 和Tomasi 的方法比较充分,并且在很多情况下可以得到比使用Harris 算法更好的结果。

    OpenCV里面的API:

    C++:void goodFeaturesToTrack( InputArray image, OutputArray corners,
                                         int maxCorners, double qualityLevel, double minDistance,
                                         InputArray mask=noArray(), int blockSize=3,

    参数详解:

    第一个参数image:8位或32位单通道灰度图像;

    第二个参数corners:位置点向量,保存的是检测到的角点的坐标;

    第三个参数maxCorners:定义可以检测到的角点的数量的最大值;

    第四个参数qualityLevel:检测到的角点的质量等级,角点特征值小于qualityLevel*最大特征值的点将被舍弃;

    第五个参数minDistance:两个角点间最小间距,以像素为单位;

    第六个参数mask:指定检测区域,若检测整幅图像,mask置为空Mat();

    第七个参数blockSize:计算协方差矩阵时窗口大小;

    第八个参数useHarrisDetector:是否使用Harris角点检测,为false,则使用Shi-Tomasi算子;

    第九个参数k:留给Harris角点检测算子用的中间参数,一般取经验值0.04~0.06。第八个参数为false时,该参数不起作用;
     

    三、亚像素级角点检测
           当我们想要进行几何测量或者标定的时候势必要比目标识别需要更高的精度的特征点。而上面的goodFeaturesToTrack()只能得到整数的坐标值,这时候我们就需要亚像素级的角点检测来得到实数坐标值来满足精度需求。

           亚像素级角点检测的位置摄像机标定,跟踪并重建摄像机的轨迹或者重建被跟踪目标的三维结构时,是一个基本的测量值。下面是将角点位置精确到亚像素精度的过程:

                                         

            一个向量与其正交的向量的点积为0,角点满足上图所示情况。其中(a)点p附近的图像是均匀的,其梯度为0;(b)边缘的梯度与沿边缘方向的q-p向量正交。在图中两种情况下,p点梯度与q-p向量的点积均为0。

          上图中,我们假设起始角点q在实际亚像素角点的附近。检测所有的q-p向量。若点p位于一个均匀区域,则点p的梯度为0。若q-p向量的方向与边缘的方向一致,则此边缘上p点处的梯度与q-p向量正交,在这两种情况下,p点处的梯度与q-p向量的点积为0.我们可以在p点周围找到很多组梯度以及相关的向量q-p,令其点集为0,然后可以通过求解方程组,方程组的解即为角点q的亚像素级精度的位置,即精确的角点位置。
     

     

    Unity for Opencv

      void Start ()
            {
                Texture2D imgTexture = Resources.Load ("lena") as Texture2D;
                
                Mat img1Mat = new Mat (imgTexture.height, imgTexture.width, CvType.CV_8UC3);
                Utils.texture2DToMat (imgTexture, img1Mat);
                Debug.Log ("img1Mat.ToString() " + img1Mat.ToString ());
    
                Texture2D imgTexture2 = Resources.Load("lena") as Texture2D;
                Mat img2Mat = new Mat (imgTexture2.height, imgTexture2.width, CvType.CV_8UC3);
                Utils.texture2DToMat (imgTexture2, img2Mat);
                Debug.Log ("img2Mat.ToString() " + img2Mat.ToString ());
    
    
                float angle = UnityEngine.Random.Range (0, 360), scale = 1.0f;
    
                Point center = new Point (img2Mat.cols () * 0.5f, img2Mat.rows () * 0.5f);
    
                Mat affine_matrix = Imgproc.getRotationMatrix2D (center, angle, scale);
    
                Imgproc.warpAffine (img1Mat, img2Mat, affine_matrix, img2Mat.size ());
    
    
                ORB detector = ORB.create ();
                ORB extractor = ORB.create ();
    
                MatOfKeyPoint keypoints1 = new MatOfKeyPoint ();
                Mat descriptors1 = new Mat ();
    
                detector.detect (img1Mat, keypoints1);
                extractor.compute (img1Mat, keypoints1, descriptors1);
    
                MatOfKeyPoint keypoints2 = new MatOfKeyPoint ();
                Mat descriptors2 = new Mat ();
            
                detector.detect (img2Mat, keypoints2);
                extractor.compute (img2Mat, keypoints2, descriptors2);
    
    
                DescriptorMatcher matcher = DescriptorMatcher.create (DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);
                MatOfDMatch matches = new MatOfDMatch ();
    
                matcher.match (descriptors1, descriptors2, matches);
    
    
                Mat resultImg = new Mat ();
    
                Features2d.drawMatches (img1Mat, keypoints1, img2Mat, keypoints2, matches, resultImg);
    
    
                Texture2D texture = new Texture2D (resultImg.cols (), resultImg.rows (), TextureFormat.RGBA32, false);
            
                Utils.matToTexture2D (resultImg, texture);
    
                gameObject.GetComponent<Renderer> ().material.mainTexture = texture;
            }
        

    如果没有明显且独立的特征点,则没法匹配。

     

    展开全文
  • Python+OpenCV实时图像处理

    万次阅读 多人点赞 2020-01-04 23:09:35
    初学OpenCV图像处理的小伙伴肯定对什么高斯函数、滤波处理、阈值二值化等特性非常头疼,这里给各位分享一个小项目,可通过摄像头实时动态查看各类图像处理的特点,也可对各位调参、测试有一定帮助。
  • OpenCV计算机视觉的常用测试图,里面包含baboon、man、monarch、sailboat、soccer、lena、tiffany等!里面还有标准测试
  • 本文介绍了HSV(也称为HSB)的OpenCV表示与标准表示的差别以及转换关系,澄清了网上其他一些资料有可能导致误解和困惑的问题,有助于大家对HSV颜色空间的概念理解和应用。
  • opencv01

    2021-02-05 15:16:53
    Opencv基本了解、图像读取和绘图 opencv简介: Opencv的组成 ​ Opencv库有核心模块库Core和扩展模块组成,他们功能如下; Core 该模块包含 OpenCV 库的基础结构以及基本操作。 Improc 图像处理模块包含基本的图像...
  • 一种用opencv实现快速求取局部标准差的方法
  • 关于OpenCV OpenCV是一个C++库,用于实时处理计算机视觉方面的问题,涵盖了很多计算机视觉领域的模块。 在Windows 上安装OpenCV-Python 一. 下载pip工具包并解压安装,python setup.... 测试是否成功安装 ...
  • 这篇文章中,我们一起探讨了如何通过已经安装的OpenCV,选择不同的编译器类型,生成高度还原的OpenCV开发时的解决方案工程文件,欣赏OpenCV新版本中总计 六十六多万行的精妙源代码。我们可以对其源代码进行再次编译...
  • Linux的OpenCV安装及测试

    千次阅读 2016-12-03 12:06:58
    安装及测试请参考: http://opencv.org/ 官网的教程很标准,比二手资料好太多。
  • OpenCV配置

    千次阅读 2018-07-17 22:39:04
    openCV环境搭建 一个新手的总结贴 从2018/7/15开始,我就开始准备搭建openCV的环境,当时准备是VS2013+openCV。参考了部分资料,均没有成功, 然后便重新安装VS2017,准备采用VS2017+openCV,在2018/7/17号...
  • 2、opencv4.0.1安装包 3、opencv4.0.1 contrib安装包,链接:https://github.com/opencv/opencv_contrib/releases?after=3.4.9 4、原contrib缺少的文件,见参考链接1,可以通过原作者下载链接,或者百度网盘下载链接...
  • OpenCV 简介

    万次阅读 2016-07-15 18:48:22
    介绍OpenCV(Open Source Computer Vision...文档OpenCV 2.x API描述的是C++ API,相对还有一个基于C语言的OpenCV 1.x API,后者的描述在文档opencv1.x.pdf中。OpenCV具有模块化结构,这就意味着开发包里面包含多个共享
  • 下载Windows版本的OpenCV-3.1.0:https://sourceforge.net/projects/opencvlibrary/files/opencv-win/3.1.0/opencv-3.1.0.exe/download 由于OpenCV是一个cmake项目,所以要编译OpenCV源码,需要先安装cmake工具。...
  • OpenCV LUT

    2019-04-14 22:18:16
    //包含OpenCV的头文件 #include <opencv2/opencv.hpp> #include <opencv2/core/mat.hpp> #include <iostream> #include <time.h> using namespace std; //使用OpenCV的命名空间 using ...
  • 最近重新开始使用opencv-cpp,有些项目需要的是OpenCV2,有些需要多是OpenCV3,这两个版本的如何共存是个值得研究多问题。这里记录一次OpenCV3和2的安装过程。 安装OpenCV3 1.源码下载 我这里使用...
  • OpenCV 2.0 测试代码

    2010-04-08 20:38:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • OpenCV编译安装

    2021-08-21 10:44:32
    最近重新开始使用opencv-cpp,有些项目需要的是OpenCV2,有些需要多是OpenCV3,这两个版本的如何共存是个值得研究多问题。这里记录一次OpenCV3和2的安装过程。 安装OpenCV3 1.源码下载 我这里使用的是OpenCV3.4.1...
  • OpenCV3.4.1+opencv_contrib编译:windows 10

    万次阅读 多人点赞 2018-06-03 18:00:08
    做计算机视觉的朋友,估计没有人没用过OpenCV,著名的开源计算机视觉算法库。OpenCV还在不断发展中,最新的3.4版本,已经可以支持cnn了,以后估计会有集成更多的功能。 不过,由于知识产权的原因,OpenCV将很多算法...
  • OpenCV 3.3.0中DNN模块测试记录

    千次阅读 2017-09-09 15:22:08
    前言:在移植OpenCV 3.3.0的过程中发现还有DNN(深层神经网络)模块,顺便就在PC上测试了其性能,没有GPU,所以只有用E3-1230v2 将就试了,从目前的接口上看貌似也不支持GPU加速。 1、使用cmake-gui设置编译选项时,...
  • OpenCV系列一 --- OpenCV简介

    千次阅读 2019-04-13 20:13:40
    该文档描述了OpenCV 2.x 的API,它本质上是一个C++ API,而不是基于C的OpenCV 1.x API(自从OpenCV 2.4发布以来,C API已被弃用,未经过“C”编译器测试)。 OpenCV具有模块化结构,这意味着该包包含多个共享库或...
  • (涉及个人隐私,源码不包含测试样本,请谅解~) 对实验结果更感兴趣的朋友请直接看 第5章 【摘要】这是一篇关于人脸识别方法的实验报告。报告首先回顾了人脸识别研究的发展历程及基本分类;随后对人脸...
  • OpenCV 4.0

    千次阅读 2018-09-29 12:15:33
    4.0 Alpha是4.0正式发布之前的第一个中间版本,如3.0正式发布前有Alpha,Beta,RC1等。 基本功能改进 1 ....在C++11中,标准的std :: string和std :: shared_ptr取代了手工制作的cv :: Stri...
  • 需要使用opencv //裁剪图片 #include <opencv2/opencv.hpp> #include "opencv2/imgproc/imgproc.hpp" using namespace cv;...//std::为C++的标准函数库 int main() { const char* filename = "../
  • 1. OpenCV 初识与安装 2. OpenCV 模块简介 3. OpenCV 图像读取,显示,保存 4. 摄像头和视频读取,保存 5. OpenCV 常用数据结构和颜色空间 6. OpenCV 常用绘图函数 7. OpenCV 界面事件操作之鼠标与滑动条 8. 图像...
  • windows下安装python+opencv测试demo

    千次阅读 2019-03-05 12:35:07
    Python是一种解释型、面向对象、动态数据类型的高级程序设计语言,适应于多种操作系统。...文章目录@[toc]下载python安装python设置环境变量查看是否安装成功使用pip安装wheel使用pip安装numpy使用pip安装opencv...
  • 学习图像识别处理中会使用带sift和surf算法,但在opencv3.0.0版本后,由于版权问题,并不会直接集成默认安装,而是和其他“non-free”被集中在opencv_contrib中,所以当需要使用此功能时,需在配置OpenCV时同OpenCV...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,474
精华内容 4,989
关键字:

opencv测试标准