AoiBlobMethod.cs 3.8 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 currentRoiImg = GetRoiImage(imageToCheck, needCut);
            resultBean.currentRoiImage = currentRoiImg;

            int num = GetBlobNum(currentRoiImg, out Image dstImg, out List<CvBlob> blobList);
            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="srcImg">原始图片</param>
        /// <param name="dstImg">二值化后的图片</param>
        /// <param name="blobList">所有的Blob</param>
        /// <returns>过滤后的Blob数量</returns>
        public int GetBlobNum(Image srcImg, out Image dstImg, out List<CvBlob> blobList)
        {
            Mat srcMat = ImageUtil.ToMat(srcImg);
            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();
            dstImg = 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;
        }
    }
}