AoiBlobMethod.cs 4.0 KB
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.Blob;
using OpenCvSharp.XFeatures2D;

namespace AOI
{
    /// <summary>
    /// 斑点分析
    /// </summary>
    public class AoiBlobMethod : AoiMethod
    {
        /// <summary>
        /// 二值化时的阈值, 小于0表示自动计算阈值,绝对值为用户设定的阈值,大于0表示按用户设置的阈值进行二值化
        /// </summary>
        public int thresh = -1;
        /// <summary>
        /// 统计Blob时,使用黑色的或白色的进行统计
        /// </summary>
        public bool whiteOnBlack = false;
        /// <summary>
        /// 过滤Blob时的最少像素数
        /// </summary>
        public int minArea = 0;
        /// <summary>
        /// 过滤Blob时的最多像素数,小于0表示不限制
        /// </summary>
        public int maxArea = -1;
        /// <summary>
        /// 经过过滤后的Blob的 最小数量
        /// </summary>
        public int minNum = 0;
        /// <summary>
        /// 经过过滤后的Blob的 最大数量, 小于0表示不限制
        /// </summary>
        public int maxNum = -1;

        public override ResultBean Check(Image standardImage, Image imageToCheck)
        {
            ResultBean resultBean = new ResultBean();
            bool needCut = true;
            Image standardRoiImg = GetRoiImage(standardImage, needCut);
            resultBean.standardRoiImage = standardRoiImg;

            Image cutImg;

            int num = GetBlobNum(imageToCheck, out cutImg, out Image dstImg, out List<CvBlob> blobList);
            resultBean.currentRoiImage = cutImg;
            bool result = false;
            if (num > minNum)
            {
                if(maxNum <= 0)
                {
                    result = true;
                }
                else if(num < maxNum)
                {
                    result = true;
                }
            }
            resultBean.result = result;
            return resultBean;
        }

        /// <summary>
        /// 对源图像进行二值化,找出所有Blob后,根据minArea和maxArea过滤Blob后的数量
        /// </summary>
        /// <param name="img">相机获取的大图</param>
        /// <param name="cutImg">从大图中切割后的原图</param>
        /// <param name="dstCutImg">切割并处理后的图片</param>
        /// <param name="blobList">所有的Blob</param>
        /// <returns>过滤后的Blob数量</returns>
        public int GetBlobNum(Image srcImg, out Image cutImg, out Image dstCutImg, out List<CvBlob> blobList)
        {
            bool needCut = true;
            cutImg = GetRoiImage(srcImg, needCut);

            Mat srcMat = ImageUtil.ToMat(cutImg);
            Mat threshMat = new Mat();
            Cv2.CvtColor(srcMat, threshMat, ColorConversionCodes.RGB2GRAY);
            ThresholdTypes threshType = ThresholdTypes.Binary;
            if (whiteOnBlack)
            {
                threshType = ThresholdTypes.BinaryInv;
            }

            if (thresh < 0)
            {
                threshType = threshType | ThresholdTypes.Otsu;
            }

            Cv2.Threshold(threshMat, threshMat, thresh, 255, threshType);

            CvBlobs blobs = new CvBlobs();
            blobs.Label(threshMat);
            blobList = blobs.Values.ToList();
            dstCutImg = ImageUtil.ToImage(threshMat);
            List<CvBlob> resultBlobs = blobList.Where(b => {
                if (b.Area > minArea)
                {
                    if (maxArea <= 0 )
                    {
                        return true;
                    }
                    else if (b.Area < maxArea)
                    {
                        return true;
                    }
                }
                return false;
            }).ToList();
            return resultBlobs.Count;
        }
    }
}