using System;
using System.Linq;
using System.Drawing;
using System.Threading;
using System.Diagnostics;
using SHJX.Service.Common.Utils;
using System.Collections.Generic;
using SHJX.Service.Common.Logging;
using Microsoft.Extensions.Logging;
using AForge.Video.DirectShow;
using SHJX.Service.Model.CRUDModules;
namespace shjxCamera
{
///
/// 图像采集器,定时进行图像采集
/// 每次采样发布采样事件:ColorDataGrabed
///
public class ColorData2Graber
{
private static readonly ILogger logger = LogFactory.BuildLogger(typeof(ColorData2Graber));
#region fields
///
/// 采集到的色彩数据队列
///
private List LstColorDataPoints;
#endregion
#region properties
///
/// 摄像头
///
public WebCamera2 WebCam { get; set; }
///
/// 提取ROI区域色彩数据
///
protected ImageRGBanalysis2 ColorAnalysis { get; set; }
///
/// 停止数据采集
///
protected bool IsStopGrab { get; set; }
///
/// 每帧间隔采集时间,毫秒
///
public int Interval { get; set; }
///
/// 图像目标区域
///
public Rectangle RectROI { get; set; }
public int CurrExposure { get; set; }
///
/// 当前状态:true=工作中,正在采集数据;false=空闲中,未采集数据;
///
public bool IsWorking { get; set; }
private Camera2Value cameraValueAll = new Camera2Value();
#endregion
#region methods
///
/// 构造色点采集器对象
///
///
public ColorData2Graber(WebCamera2 webcam)
{
WebCam = webcam ?? new WebCamera2();
ColorAnalysis = new ImageRGBanalysis2();
RectROI = new Rectangle(0, 0, 10, 10);
LstColorDataPoints = new List();
Interval = 50;
IsStopGrab = false;
IsWorking = false;
}
///
/// 自动调整目标取图区域的位置
///
public Rectangle UpdateRoiPos(bool writeFlag)
{
try
{
Bitmap imgBitmap = WebCam.GrabImage2();
if (imgBitmap == null)
{
int cnt = 30;
while (imgBitmap == null && cnt-- > 0)
{
logger.LogError(string.Format("摄像头2imgBitmap2 == null && cnt-- > 0"));
Thread.Sleep(100);
imgBitmap = WebCam.GrabImage2();
}
if (imgBitmap == null)
{
logger.LogError(string.Format("摄像头2imgBitmap2 == null"));
return Titration2Settings.SensorPara.RoiSample;
}
}
//Random rd = new Random();
//string name = System.DateTime.Now.ToString("yyyyMMddHHmmss") + rd.ToString() + ".bmp";
//imgBitmap.Save("C:\\Users\\25109\\Desktop\\软件版本库\\测试文件\\高锰测试\\摄像2图片\\"+ name);
logger.LogCritical(string.Format("22222222old roi=({0}, {1}, {2}, {3})", RectROI.X, RectROI.Y, RectROI.Right, RectROI.Bottom));
RectROI = ColorAnalysis.GetRoiPos(imgBitmap, Titration2Settings.SensorPara.RoiSample, 35); // 定位新的目标区域坐标
RectROI.Offset(Titration2Settings.SensorPara.RoiOffsetX, 0); // 加入偏移量
if (Titration2Settings.SensorPara.UseRoiMask)
{
// 计算目标区域的均值,以均值的1/2作为阈值查找RoiMask
int sumR = 0, sumG = 0, sumB = 0;
ColorAnalysis.GetTotalFromImage(imgBitmap, RectROI, ref sumR, ref sumG, ref sumB);
sumB = Math.Min(10, sumB / (RectROI.Width * RectROI.Height) / 2);
#region 检查信号值是否异常[=0]
if (sumB < 0.5)
{
throw new Exception("信号值异常[0],滴定须终止。");
}
#endregion
Titration2Settings.SensorPara.RoiMaskPoints = ColorAnalysis.GetRoiMask(imgBitmap, RectROI, sumB);
}
logger.LogCritical(string.Format("22222222new roi=({0}, {1}, {2}, {3}), offset=({4},0)", RectROI.X, RectROI.Y, RectROI.Right, RectROI.Bottom, Titration2Settings.SensorPara.RoiOffsetX));
if (writeFlag)
{
ColorAnalysis.WriteRGBlog(imgBitmap, RectROI, "定位后数据" + RectROI.ToString());
}
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
}
return RectROI;
}
///
/// 自动调节曝光值
///
public void PresetLightParam(int maxRange)
{
logger.LogCritical("22222222自动调节曝光值");
WebCam.SetProperties(CameraControlProperty.Exposure, maxRange,CameraControlFlags.Manual);
WebCam.GetPropertiesRange(CameraControlProperty.Exposure, out var min, out var max, out var size, out var value, out var flag);
Thread.Sleep(1000); //min=-9,max=0;size=1;value=-7;flag=Manual;
// 读取信号值
var cdp = GrabSignal(500);
// 判断信号所在区间,小于额定值范围则缩小曝光值,大于额定范围则增大曝光值
CameraControlFlags flags = CameraControlFlags.Manual;
WebCam.GetProperties(CameraControlProperty.Exposure, out int val, out flags);
int maxcount = 10;
double bsvBelow = 114;
double bsvUp = 114;
int valBelow = -9;
int valUp = 0;
double bsv = 0.0;
bool flagJudge = true; ;
while (maxcount > 0)
{
maxcount--;
bsv = cdp.GetBSV();
if (bsv < 110)
{
bsvBelow = bsv;
if (val.Equals(min))
break;
val = Math.Min(max, Math.Max(maxRange, val - 1));
valBelow = val;
logger.LogCritical($"22222222增大曝光值为:{val}");
}
else if (bsv > 118)
{
bsvUp = bsv;
if (val.Equals(max))
break;
val = Math.Min(max, Math.Max(maxRange, val + 1));
valUp = val;
logger.LogCritical($"22222222减少曝光值为:{val}");
}
else
{
flagJudge = false; ;
break;
}
WebCam.SetProperties(CameraControlProperty.Exposure, val, CameraControlFlags.Manual);
Thread.Sleep(500);
UpdateRoiPos(false);
cdp = GrabSignal(500);
}
if (flagJudge)
{
val = 114 - bsvBelow > bsvUp - 114 ? valBelow : valUp;
val = Math.Min(max, Math.Max(maxRange, val));
WebCam.SetProperties(CameraControlProperty.Exposure, val, CameraControlFlags.Manual);
Thread.Sleep(500);
ContinuePresetLightParam();
}
WebCam.GetProperties(CameraControlProperty.Exposure, out val, out flags);
CurrExposure = val;
logger.LogCritical($"22222222新的曝光值为:{val}");
}
public void ContinuePresetLightParam()
{
logger.LogCritical("22222222自动调节亮度值Brightness");
WebCam.GetVideoProcAmpPropertiesRange(VideoProcAmpProperty.Brightness, out var minb, out var maxb, out var sizeb, out var valueb, out var flagb);
Thread.Sleep(1000);
// 读取信号值
var cdp = GrabSignal(500);
VideoProcAmpFlags flags = VideoProcAmpFlags.Manual;
WebCam.GetVideoProcAmpProperties(VideoProcAmpProperty.Brightness, out int val, out flags);
int maxcount = 40;
while (maxcount > 0)
{
maxcount--;
if (cdp.GetBSV() < 110)
{
if (val < minb) break;
val = val + 1;
logger.LogCritical($"22222222增大亮度值为:{val}");
}
else if (cdp.GetBSV() > 118)
{
if (val > maxb) break;
val = val - 1;
logger.LogCritical($"22222222减少亮度值为:{val}");
}
else
{
break;
}
WebCam.SetVideoProcAmpProperties(VideoProcAmpProperty.Brightness, val, VideoProcAmpFlags.Manual);
Thread.Sleep(500);
UpdateRoiPos(false);
cdp = GrabSignal(500);
}
if (cdp.GetBSV() > 118)
{logger.LogCritical($"22222222新的亮度值为:{val}");
PresetLightParammanual(cameraValueAll, 10);
}
WebCam.GetVideoProcAmpProperties(AForge.Video.DirectShow.VideoProcAmpProperty.Brightness, out val, out flagb);
CurrExposure = val;
logger.LogCritical($"22222222新的亮度值为:{val}");
}
public void PresetLightParammanual(Camera2Value cameraValue, int explosionRange)
{
cameraValueAll = cameraValue;
//WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Brightness, out var minb, out var maxb, out var sizeb, out var valueb, out var flagb);
//WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Contrast, out var minbc, out var maxbc, out var sizebc, out var valuebc, out var flagbc);
//WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Hue, out var minbh, out var maxbh, out var sizebh, out var valuebh, out var flagbh);
//WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Saturation, out var minbs, out var maxbs, out var sizebs, out var valuebs, out var flagbs);
//WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Sharpness, out var mins, out var maxs, out var sizes, out var values, out var flags);
//WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.WhiteBalance, out var minbw, out var maxbw, out var sizebw, out var valuebw, out var flagbw);
//WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Gain, out var minbg, out var maxbg, out var sizebg, out var valuebg, out var flagbg);
WebCam.SetVideoProcAmpProperties(VideoProcAmpProperty.Brightness, cameraValue.Brightness, VideoProcAmpFlags.Manual);
WebCam.SetVideoProcAmpProperties(VideoProcAmpProperty.Contrast, cameraValue.Contrast, VideoProcAmpFlags.Manual);
WebCam.SetVideoProcAmpProperties(VideoProcAmpProperty.Sharpness, cameraValue.Sharpness, VideoProcAmpFlags.Manual);
WebCam.SetVideoProcAmpProperties(VideoProcAmpProperty.Gain, cameraValue.Gain, VideoProcAmpFlags.Manual);
//WebCam.SetVideoProcAmpProperties(VideoProcAmpProperty.Hue, 0, VideoProcAmpFlags.Manual);
WebCam.SetVideoProcAmpProperties(VideoProcAmpProperty.Saturation, cameraValue.Saturation, VideoProcAmpFlags.Manual);
WebCam.SetVideoProcAmpProperties(VideoProcAmpProperty.WhiteBalance, cameraValue.WhiteBalance, VideoProcAmpFlags.Manual);
if (explosionRange!=10)
{
WebCam.SetProperties(CameraControlProperty.Exposure, explosionRange, CameraControlFlags.Manual);
}
Thread.Sleep(1000);
UpdateRoiPos(true);
GrabSignal(10);
int threshold_gray = 5; // 色点过滤阈值
int threshold_hue = 5; // 色相偏移阈值
ColorPoint cp = Globals.Camera.SampleBackground("d1camera", threshold_gray, threshold_hue);
//logger.LogCritical($"22222222亮度:{cameraValue.Brightness} 对比:{cameraValue.Contrast} 锐度:{cameraValue.Sharpness} 增益:{cameraValue.Gain} 曝光:{explosionRange};***色值:{cp.Hue}");
logger.LogCritical($"22222222亮度:{cameraValue.Brightness} 对比:{cameraValue.Contrast} 饱和度:{cameraValue.Saturation}" +
$" 白平衡:{cameraValue.WhiteBalance} 锐度:{cameraValue.Sharpness} 增益:{cameraValue.Gain} 曝光: {explosionRange};***色值:{cp.Hue}");
//Random rd = new Random();
//string name = System.DateTime.Now.ToString("yyyyMMddHHmmss") + rd.ToString() + ".bmp";
//imgBitmap.Save("C:\\Users\\25109\\Desktop\\软件版本库\\测试文件\\高锰测试\\摄像2图片\\"+ name);
}
public void ShowParammanual()
{
// WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Brightness, out var minb, out var maxb, out var sizeb, out var valueb, out var flagb);
// WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Contrast, out var minbc, out var maxbc, out var sizebc, out var valuebc, out var flagbc);
// WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Hue, out var minbh, out var maxbh, out var sizebh, out var valuebh, out var flagbh);
// WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Saturation, out var minbs, out var maxbs, out var sizebs, out var valuebs, out var flagbs);
// WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Sharpness, out var mins, out var maxs, out var sizes, out var values, out var flags);
// WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.WhiteBalance, out var minbw, out var maxbw, out var sizebw, out var valuebw, out var flagbw);
// WebCam.GetVideoProcAmpPropertiesRange(AForge.Video.DirectShow.VideoProcAmpProperty.Gain, out var minbg, out var maxbg, out var sizebg, out var valuebg, out var flagbg);
WebCam.GetVideoProcAmpProperties(AForge.Video.DirectShow.VideoProcAmpProperty.Brightness, out var valuebb, out var flagbb);
WebCam.GetVideoProcAmpProperties(AForge.Video.DirectShow.VideoProcAmpProperty.Contrast, out var valuebcc, out var flagbcc);
WebCam.GetVideoProcAmpProperties(AForge.Video.DirectShow.VideoProcAmpProperty.Hue, out var valuebhh, out var flagbhh);
WebCam.GetVideoProcAmpProperties(AForge.Video.DirectShow.VideoProcAmpProperty.Saturation, out var valuebss, out var flagbss);
WebCam.GetVideoProcAmpProperties(AForge.Video.DirectShow.VideoProcAmpProperty.Sharpness, out var valuess, out var flagss);
WebCam.GetVideoProcAmpProperties(AForge.Video.DirectShow.VideoProcAmpProperty.WhiteBalance, out var valuebww, out var flagbww);
WebCam.GetVideoProcAmpProperties(AForge.Video.DirectShow.VideoProcAmpProperty.Gain, out var valuebgg, out var flagbgg);
WebCam.GetProperties(CameraControlProperty.Exposure, out var exposure, out var flagex);
logger.LogCritical($"22222222亮度:{valuebb} 对比:{valuebcc} 锐度:{valuess} 饱和度:{valuebss} 白平衡:{valuebww} 增益:{valuebgg} 曝光:{exposure} ");
}
///
/// 连续采集指定时长的信号值,计算并返回该时长的信号总值和均值
///
/// 指定采集时长
/// 信号统计数据
public ColorData2Point GrabSignal(int milsecCount)
{
if (milsecCount < 35) milsecCount = 500;
IsWorking = true;
ColorData2Point cdp;
var rectRoi = RectROI;
int vr = 0, vg = 0, vb = 0;
var area = rectRoi.Width * rectRoi.Height;
if (Titration2Settings.SensorPara.UseRoiMask && Titration2Settings.SensorPara.RoiMaskPoints is not null)
{
area = Titration2Settings.SensorPara.RoiMaskPoints.Count;
}
// 采集指定时长的数据,计算均值返回
LstColorDataPoints.Clear();
var timeLength = 0;
IsStopGrab = false;
var sw = new Stopwatch();
while (!IsStopGrab)
{
sw.Restart();
var bmp = WebCam.GrabImage2();
if (Titration2Settings.SensorPara.UseRoiMask && Titration2Settings.SensorPara.RoiMaskPoints != null)
{
ColorAnalysis.GetTotalFromImage(bmp, Titration2Settings.SensorPara.RoiMaskPoints, ref vr, ref vg, ref vb);
}
else
{
ColorAnalysis.GetTotalFromImage(bmp, rectRoi, ref vr, ref vg, ref vb);
}
//Random rd = new Random();
//string name = System.DateTime.Now.ToString("yyyyMMddHHmmss") + rd.Next().ToString() + ".bmp";
//bmp.Save("C:\\Users\\25109\\Desktop\\软件版本库\\测试文件\\高锰测试\\摄像2图片\\" + name);
cdp = new ColorData2Point { Id = LstColorDataPoints.Count, Area = area, RTV = vr, GTV = vg, BTV = vb };
LstColorDataPoints.Add(cdp); // 加入队列保存
// 固定每帧图像间隔
if (sw.ElapsedMilliseconds >= Interval)
{
sw.Stop();
}
else
{
Thread.Sleep(Interval - Convert.ToInt32(sw.ElapsedMilliseconds));
}
// 是否已到指定时长,结束采集
timeLength += Interval;
if (timeLength >= milsecCount)
{
break;
}
}
var lstSort = LstColorDataPoints.OrderByDescending(c => c.GTV).ToList();
var nMedianPos = Convert.ToInt32(Math.Ceiling(lstSort.Count / 2.0));
cdp = lstSort[nMedianPos - 1];
logger.LogCritical($"22222222use r={cdp.GetRSV()},g={cdp.GetGSV()},b={cdp.GetBSV()},h={cdp.GetSaturation()}");
IsWorking = false;
Messager