188 lines
6.3 KiB
C#
188 lines
6.3 KiB
C#
/*
|
|
* Copyright (c) 2025 LG Electronics Inc.
|
|
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
|
|
*/
|
|
using Aurora.Api;
|
|
using VisionCommon;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reactive.Linq;
|
|
|
|
namespace VisionSequence.Camera {
|
|
/// <summary>
|
|
/// 공정에서 사용되는 이미지의 정보
|
|
/// </summary>
|
|
public class ImageInfo : IDisposable {
|
|
/// <summary>공정 이미지</summary>
|
|
public object Image { get; set; } = null;
|
|
/// <summary>점유(사용) 상태 플래그</summary>
|
|
public bool Occupied { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// 생성자
|
|
/// </summary>
|
|
/// <param name="image">공정 이미지</param>
|
|
/// <param name="occupied">점유(사용) 상태 플래그</param>
|
|
public ImageInfo(object image, bool occupied) {
|
|
Image = image;
|
|
Occupied = occupied;
|
|
}
|
|
/// <summary>
|
|
/// 명시적 해제 (이미지 메모리 해제, Occupied = false)
|
|
/// </summary>
|
|
public void Dispose() {
|
|
IpAdapter.Instance.IpEnvironment.FreeImage(Image);
|
|
Image = null;
|
|
Occupied = false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 공정 이미지 매니저로 그랩 횟수를 최소화하기 위해 사용한다.
|
|
/// 패턴에서 동일한 조명 값을 사용하는 경우 카메라 그랩을 1회만 수행한다.
|
|
/// </summary>
|
|
public class ProcGrabImageManager : IDisposable {
|
|
private readonly object _Lock = new object();
|
|
private List<ImageInfo> _ImageInfos = new List<ImageInfo>();
|
|
private Dictionary<LightInfo, object> _GrabImages = new Dictionary<LightInfo, object>();
|
|
private Logger _Logger;
|
|
private FovInfo _FovInfo;
|
|
private CameraAgentBase _CameraAgent;
|
|
private IDisposable _EventDisposable;
|
|
|
|
/// <summary>
|
|
/// 생성자
|
|
/// </summary>
|
|
/// <param name="fovInfo">FOV 키 정보</param>
|
|
/// <param name="cameraAgent">카메라 에이전트</param>
|
|
public ProcGrabImageManager(FovInfo fovInfo, CameraAgentBase cameraAgent) {
|
|
_Logger = new Logger(GetType().Name);
|
|
_FovInfo = fovInfo;
|
|
_CameraAgent = cameraAgent;
|
|
SetObservable();
|
|
}
|
|
|
|
private void SetObservable() {
|
|
var camRecipe = VisionRecipeManager.GetCamRecipe(_FovInfo);
|
|
if (_EventDisposable == null) {
|
|
_EventDisposable = VisionEnv.AuroraEnv.EventObservable.AsObservable(VisionEventId.UPDATE_GRAB_IMAGE_BUFFER).
|
|
Where(x => x.From == camRecipe.CamId.ToString()).
|
|
Subscribe(_ => UpdateGrabImageBuffer());
|
|
}
|
|
}
|
|
|
|
private void UpdateGrabImageBuffer() {
|
|
lock (_Lock) {
|
|
if (0 < _ImageInfos.Count) {
|
|
var camImageSize = _CameraAgent.GetImageSize();
|
|
var imageSize = IpAdapter.Instance.IpEnvironment.GetImageSize(_ImageInfos[0].Image);
|
|
|
|
if (!IpAdapter.Instance.IpEnvironment.ImageSizeEquals(camImageSize, imageSize)) {
|
|
DisposeImageInfos();
|
|
Clear();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 공정 이미지 초기화
|
|
/// </summary>
|
|
public void Clear() {
|
|
lock (_Lock) {
|
|
_GrabImages.Clear();
|
|
ClearOccupied();
|
|
}
|
|
}
|
|
|
|
private void ClearOccupied() {
|
|
lock (_Lock) {
|
|
foreach (var imageInfo in _ImageInfos) {
|
|
imageInfo.Occupied = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 조명 값(LightInfo)의 공정 이미지 그랩 완료 여부
|
|
/// </summary>
|
|
/// <param name="lightInfo">조명 값</param>
|
|
/// <returns>완료 여부</returns>
|
|
public bool IsGrabDone(LightInfo lightInfo) {
|
|
lock (_Lock) {
|
|
return _GrabImages.ContainsKey(lightInfo);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 조명 값(LightInfo)으로 그랩된 공정 이미지를 등록
|
|
/// </summary>
|
|
/// <param name="lightInfo">조명 값</param>
|
|
/// <param name="image">공정 이미지</param>
|
|
public void SetGrabImage(LightInfo lightInfo, object image) {
|
|
lock (_Lock) {
|
|
if (_GrabImages.ContainsKey(lightInfo)) {
|
|
_GrabImages[lightInfo] = image;
|
|
}
|
|
else {
|
|
_GrabImages.Add(lightInfo, image);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 공정이미지를 얻어 온다.
|
|
/// </summary>
|
|
/// <param name="lightInfo">조명 값</param>
|
|
/// <returns>공정 이미지</returns>
|
|
public object GetGrabImage(LightInfo lightInfo) {
|
|
lock (_Lock) {
|
|
if (_GrabImages.ContainsKey(lightInfo)) {
|
|
return _GrabImages[lightInfo];
|
|
}
|
|
else {
|
|
_GrabImages[lightInfo] = GetImage();
|
|
return _GrabImages[lightInfo];
|
|
}
|
|
}
|
|
}
|
|
|
|
private object GetImage() {
|
|
lock (_Lock) {
|
|
foreach (var imageInfo in _ImageInfos) {
|
|
if (!imageInfo.Occupied) {
|
|
imageInfo.Occupied = true;
|
|
return imageInfo.Image;
|
|
}
|
|
}
|
|
var newImageInfo = CreateImageInfo();
|
|
_ImageInfos.Add(newImageInfo);
|
|
|
|
return newImageInfo.Image;
|
|
}
|
|
}
|
|
|
|
private ImageInfo CreateImageInfo() {
|
|
return new ImageInfo(_CameraAgent.CloneImageBuffer(), occupied: true);
|
|
}
|
|
/// <summary>
|
|
/// 명시적 해제
|
|
/// </summary>
|
|
public void Dispose() {
|
|
lock (_Lock) {
|
|
DisposeImageInfos();
|
|
_EventDisposable.Dispose();
|
|
}
|
|
}
|
|
|
|
private void DisposeImageInfos() {
|
|
lock (_Lock) {
|
|
foreach (var imageInfo in _ImageInfos) {
|
|
imageInfo.Dispose();
|
|
}
|
|
_ImageInfos.Clear();
|
|
}
|
|
}
|
|
}
|
|
}
|