2026-01-26 14:51:28 +09:00

1105 lines
42 KiB
C#

/*
* Copyright (c) 2025 LG Electronics Inc.
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
*/
using Aurora.Api;
using Aurora.Api.DataType;
using VisionCommon;
using Hermes;
using Cognex.VisionPro;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Drawing;
using Aurora;
using System.Windows.Media.Imaging;
using System.Drawing.Imaging;
using Cognex.VisionPro.ImageFile;
using System.Runtime.InteropServices;
using Cognex.VisionPro.Display;
using System.Linq;
using Cognex.VisionPro.ImageProcessing;
using VisionCommonUI;
using VisionCommonUI.Resources;
namespace CogCommon {
/// <summary>
/// Cognex 환경 변수 및 메소드 관리
/// </summary>
public class CogEnvironment : IDisposable {
private static readonly Logger _Logger = new Logger("CogEnvironment");
private static object LockObj = new object();
//private MIL_INT _LicenseModules = 0;
private static CogEnvironment _instance = null;
/// <summary>
/// 싱글톤 객체
/// </summary>
public static CogEnvironment Instance {
get {
lock (LockObj) {
if (_instance == null) {
_instance = new CogEnvironment();
}
return _instance;
}
}
}
private CogEnvironment() {
IpAdapter.Instance.IpEnvironment = new IpEnvironment();
CheckLangToken();
CheckCogVersion();
}
private void CheckLangToken() {
string lastLanguage = (VisionEnv.AuroraEnv.SettingEntry[AuroraSettings.Equipment] as EquipmentInfo)?.Language ?? null;
if (lastLanguage != null && lastLanguage.Length > 0) {
System.Globalization.CultureInfo.CurrentCulture = new System.Globalization.CultureInfo(lastLanguage);
StrTokens.Culture = System.Globalization.CultureInfo.CurrentCulture;
}
}
private void CheckCogVersion() {
if (!VersionChecker.CheckCogVersionAndType()) {
MessageBoxUtil.ShowMessageBoxWarning(
string.Format(StrTokens.MSG_W_CogVersion, VersionChecker.GetCogVersion(), VersionChecker.GetCogType()));
}
}
/// <summary>
/// Cognex 라이센스 체크.
/// 대략 70ms이상이 소요되므로, 프로그램 시작시 최초 1번만 수행할 것을 권장
/// </summary>
/// <returns>라이센스 여부</returns>
public bool HasValidLicense() {
return CogLicense.IsLicenseEnabled(CogLicenseConstants.Generic, false);
}
/// <summary>
/// 리소스 회수
/// </summary>
public void Dispose() {
}
/// <summary>
/// 원본 이미지 할당
/// </summary>
/// <param name="image">원본 이미지 버퍼</param>
/// <param name="camConfig">카메라 컨피그</param>
/// <returns>성공 유무</returns>
public int AllocOriginalImage(CamConfig camConfig, ref ICogImage image) {
switch (camConfig.ImageSize.Channel) {
case 1:
// 원본이미지는 항상 정사이즈 (W > H)
image = new CogImage8Grey(camConfig.ImageSize.Width, camConfig.ImageSize.Height);
return E1.OK;
case 3:
default:
// 원본이미지는 항상 정사이즈 (W > H)
image = new CogImage8Grey(camConfig.ImageSize.Width, camConfig.ImageSize.Height);
return E1.OK;
}
}
/// <summary>
/// GrayScale 이미지 할당
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <param name="image">결과 이미지</param>
/// <returns>성공 유무</returns>
public int AllocGrayImage(CamConfig camConfig, bool isCropped, ref ICogImage image) {
if (IsHeightLongerThanWidth(camConfig)) {
return AllocGrayImage_HLongerThanW(camConfig, isCropped, ref image);
}
else {
return AllocGrayImage_WLongerThanH(camConfig, isCropped, ref image);
}
}
/// <summary>
/// Color 이미지 할당
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <param name="image">결과 이미지</param>
/// <returns>성공 유무</returns>
public int AllocColorImage(CamConfig camConfig, bool isCropped, ref ICogImage image) {
if (IsHeightLongerThanWidth(camConfig)) {
return AllocColorImage_HLongerThanW(camConfig, isCropped, ref image);
}
else {
return AllocColorImage_WLongerThanH(camConfig, isCropped, ref image);
}
}
private int AllocGrayImage_HLongerThanW(CamConfig camConfig, bool isCropped, ref ICogImage image) { // Gray (H > W)
image = new CogImage8Grey(
isCropped ? (int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY) : camConfig.ImageSize.Height,
isCropped ? (int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX) : camConfig.ImageSize.Width);
return E1.OK;
}
private int AllocGrayImage_WLongerThanH(CamConfig camConfig, bool isCropped, ref ICogImage image) { // Gray (W > H)
image = new CogImage8Grey(
isCropped ? (int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX) : camConfig.ImageSize.Width,
isCropped ? (int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY) : camConfig.ImageSize.Height);
return E1.OK;
}
private int AllocColorImage_HLongerThanW(CamConfig camConfig, bool isCropped, ref ICogImage image) { // Color (H > W)
image = new CogImage24PlanarColor(
isCropped ? (int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY) : camConfig.ImageSize.Height,
isCropped ? (int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX) : camConfig.ImageSize.Width);
return E1.OK;
}
private int AllocColorImage_WLongerThanH(CamConfig camConfig, bool isCropped, ref ICogImage image) { // Color (W > H)
image = new CogImage24PlanarColor(
isCropped ? (int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX) : camConfig.ImageSize.Width,
isCropped ? (int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY) : camConfig.ImageSize.Height);
return E1.OK;
}
/// <summary>
/// 이미지 세로 사이즈가 가로 사이즈보다 큰지 확인
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <returns>이미지 세로 사이즈가 가로 사이즈보다 크면 True</returns>
public bool IsHeightLongerThanWidth(CamConfig camConfig) {
switch (camConfig.FlipAndRotation.ImageRotation) {
case eImageRotation.CW_DEG_90:
case eImageRotation.CW_DEG_270:
return true;
}
return false;
}
/// <summary>
/// 이미지 반전 유무 확인
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <returns>이미지 반전 유무</returns>
public bool IsFlipEnabled(CamConfig camConfig) {
if (camConfig.FlipAndRotation.ImageFlip.Equals(eImageFlip.None))
return false;
else
return true;
}
/// <summary>
/// 이미지 회전 유무 확인
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <returns>이미지 회전 유무</returns>
public bool IsRotationEnabled(CamConfig camConfig) {
if (camConfig.FlipAndRotation.ImageRotation.Equals(eImageRotation.None) &&
camConfig.FlipAndRotation.ImageRotationOffset == 0)
return false;
else
return true;
}
/// <summary>
/// 이미지 저장
/// </summary>
/// <param name="filePath">파일 경로</param>
/// <param name="image">이미지</param>
/// <param name="roi">ROI</param>
/// <returns>성공 유무</returns>
public static int SaveImage(string filePath, ICogImage image, Rect roi) {
try {
ICogImage childImage = CropImage(image, roi);
SaveImage(filePath, childImage);
}
catch (Exception e) {
_Logger.FuncE(e.Message);
return E1.GENERIC;
}
return E1.OK;
}
/// <summary>
/// 이미지 저장
/// </summary>
/// <param name="filePath">파일 경로</param>
/// <param name="image">이미지</param>
/// <param name="imageFormat">이미지 형식</param>
/// <returns>성공 유무</returns>
public static int SaveImage(string filePath, ICogImage image, eImageFormat imageFormat = eImageFormat.PNG) {
try {
var dirPath = Path.GetDirectoryName(filePath);
if (!Directory.Exists(dirPath)) {
new DirectoryInfo(dirPath).Create();
}
ICogImageFileProvider cogImageFile = GetCogImageFileFormat(imageFormat);
cogImageFile.Open(filePath, CogImageFileModeConstants.Write);
cogImageFile.Append(image);
cogImageFile.Close();
#region 기존
//using (var ms = new MemoryStream())
//using (var fs = new FileStream(filePath, FileMode.Create)) {
// var bitmapSource = ConvertToBitmapSource(image);
// var encoder = new PngBitmapEncoder();
// encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
// encoder.Save(ms);
// var data = ms.ToArray();
// fs.Write(data, 0, data.Length);
//}
#endregion
}
catch (Exception e) {
_Logger.FuncE(e.Message);
return E1.GENERIC;
}
return E1.OK;
}
private static ICogImageFileProvider GetCogImageFileFormat(eImageFormat imageFormat) {
switch (imageFormat) {
case eImageFormat.PNG:
return new CogImageFilePNG();
case eImageFormat.BMP:
return new CogImageFileBMP();
case eImageFormat.JPG:
return new CogImageFileJPEG();
}
return new CogImageFilePNG();
}
/// <summary>
/// 이미지 저장
/// </summary>
/// <param name="filePath">파일 경로</param>
/// <param name="image">이미지</param>
/// <param name="imageFormat">이미지 형식</param>
/// <returns>성공 유무</returns>
public static int SaveImage(string filePath, Bitmap image, eImageFormat imageFormat = eImageFormat.PNG) {
ImageFormat imageFileFormat = GetBitmapImageFileFormat(imageFormat);
image.Save(filePath, imageFileFormat);
return E1.OK;
}
private static ImageFormat GetBitmapImageFileFormat(eImageFormat imageFormat) {
switch (imageFormat) {
case eImageFormat.PNG:
return ImageFormat.Png;
case eImageFormat.BMP:
return ImageFormat.Bmp;
case eImageFormat.JPG:
return ImageFormat.Jpeg;
}
return ImageFormat.Png;
}
private static BitmapSource ConvertToBitmapSource(ICogImage cogImage) {
try {
using (var pixelMemory = ((CogImage8Grey)cogImage).Get8GreyPixelMemory(
CogImageDataModeConstants.Read,
0, 0, cogImage.Width, cogImage.Height)) {
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(pixelMemory.Stride) * pixelMemory.Height;
byte[] pixelValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(pixelMemory.Scan0, pixelValues, 0, bytes);
return BitmapSource.Create(
cogImage.Width, cogImage.Height, 96, 96,
System.Windows.Media.PixelFormats.Gray8, null, pixelValues, pixelMemory.Stride);
}
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return null;
}
//public static void SaveImage(string path, Bitmap bitmap) {
// try {
// using (var ms = new MemoryStream())
// using (var fs = new FileStream(path, FileMode.Create)) {
// var bitmapImage = ConvertToBitmapImage(bitmap);
// if (bitmapImage != null) {
// var encoder = new JpegBitmapEncoder() { QualityLevel = 100 };
// encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
// encoder.Save(ms);
// var data = ms.ToArray();
// fs.Write(data, 0, data.Length);
// }
// }
// }
// catch (Exception e) {
// _Logger.FuncE(e.Message);
// }
//}
/// <summary>
/// Bitmap을 BitmapImage로 변환
/// </summary>
/// <param name="bitmap">비트맵</param>
/// <returns>비트맵 이미지</returns>
public static BitmapImage ConvertToBitmapImage(Bitmap bitmap) {
try {
BitmapImage image;
using (var memory = new MemoryStream()) {
bitmap.Save(memory, ImageFormat.Bmp);
memory.Position = 0;
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
image = bitmapImage;
}
return image;
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return null;
}
/// <summary>
/// 이미지 불러오기
/// </summary>
/// <param name="filePath">파일 경로</param>
/// <returns>이미지</returns>
public static ICogImage LoadImage(string filePath) {
ICogImage loadImage = null;
try {
if (!File.Exists(filePath)) {
return null;
}
using (CogImageFile ImageFile = new CogImageFile()) {
ImageFile.Open(filePath, CogImageFileModeConstants.Read);
loadImage = ImageFile[0] as ICogImage;
ImageFile.Close();
}
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return loadImage;
}
/// <summary>
/// 이미지 사이즈와 픽셀 데이터만 복사
/// </summary>
/// <param name="srcImage">소스 이미지</param>
/// <param name="dstImage">복사 이미지</param>
/// <returns>성공 유무</returns>
public static int CopyImage(ICogImage srcImage, ref ICogImage dstImage) {
try {
if (srcImage == null) {
_Logger.FuncE("srcImage is null");
return E1.GENERIC;
}
if (dstImage == null) {
_Logger.FuncE("dstImage is null");
return E1.GENERIC;
}
using (var copyRegionTool = new CogCopyRegionTool()) {
copyRegionTool.InputImage = srcImage;
copyRegionTool.DestinationImage = dstImage;
copyRegionTool.Region = null; // 설정 필수 : 이미지 전체 영역
copyRegionTool.Run();
}
}
catch (Exception e) {
_Logger.FuncE(e.Message);
return E1.GENERIC;
}
return E1.OK;
}
/// <summary>
/// 새로운 이미지 복제. 반복 남용시 메모리 누수가 발생할 수 있음.
/// </summary>
/// <param name="image">소스 이미지</param>
/// <returns>복제 이미지</returns>
public static ICogImage CloneImage(ICogImage image) {
return image.CopyBase(CogImageCopyModeConstants.CopyPixels); // new CogImage8Grey((CogImage8Grey)image)와 동일
}
/// <summary>
/// 이미지 자르기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="rect">자를 영역</param>
/// <returns>자른 이미지</returns>
public static ICogImage CropImage(ICogImage image, Rect rect) {
var imageSize = GetImageSize(image);
if (imageSize.Width > rect.Width && imageSize.Height > rect.Height) {
var convertTool = new CogImageConvertTool();
convertTool.InputImage = image;
convertTool.Region = ConvertToCogRectangle(rect);
convertTool.Run();
//convertTool.OutputImage.PixelFromRootTransform = new CogTransform2DLinear(); // 상대 좌표계로 리셋
return convertTool.OutputImage;
}
else {
return image;
}
}
/// <summary>
/// 이미지 자르기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="roi">자를 영역</param>
/// <returns>자른 이미지</returns>
public static ICogImage CropImage(ICogImage image, ROI roi) {
var imageSize = GetImageSize(image);
if (imageSize.Width > roi.Width && imageSize.Height > roi.Height) {
var convertTool = new CogImageConvertTool();
convertTool.InputImage = image;
convertTool.Region = ConvertToCogRectangleAffine(roi);
convertTool.Run();
//convertTool.OutputImage.PixelFromRootTransform = new CogTransform2DLinear(); // 상대 좌표계로 리셋
return convertTool.OutputImage;
}
else {
return image;
}
}
/// <summary>
/// 이미지 자원 회수
/// </summary>
/// <param name="image">이미지</param>
/// <returns>성공 유무</returns>
public static int FreeImage(ICogImage image) {
if (image != null) {
(image as CogImage8Grey).Dispose();
}
return E1.OK;
}
/// <summary>
/// 사각영역 중심 가져오기
/// </summary>
/// <param name="roi">사각영역</param>
/// <returns>사각영역 중심</returns>
public static ImagePoint GetRectCenter(Rect roi) {
return new ImagePoint(roi.Left + roi.Width / 2, roi.Top + roi.Height / 2);
}
/// <summary>
/// 이미지 중심 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <returns>이미지 중심</returns>
public static ImagePoint GetImageCenter(ICogImage image) {
var imageSize = GetImageSize(image);
return new ImagePoint(
imageSize.Width * 0.5,
imageSize.Height * 0.5);
}
/// <summary>
/// 이미지 크기 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <returns>이미지 크기</returns>
public static ImageSize GetImageSize(ICogImage image) {
int width = -1;
int height = -1;
int band = -1;
int bitDepth = -1;
try {
width = image.Width;
height = image.Height;
band = 1;
bitDepth = 8;
}
catch (Exception e) {
}
return new ImageSize() {
Width = width,
Height = height,
Channel = band,
BitDepth = bitDepth
};
}
/// <summary>
/// 이미지 사이즈 가져오기
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <returns>성공 유무</returns>
public ImageSize GetImageSize(CamConfig camConfig) {
var imageSize = new ImageSize();
if (IsHeightLongerThanWidth(camConfig)) {
imageSize.Width = camConfig.ImageSize.Height;
imageSize.Height = camConfig.ImageSize.Width;
}
else {
imageSize.Width = camConfig.ImageSize.Width;
imageSize.Height = camConfig.ImageSize.Height;
}
imageSize.Channel = camConfig.ImageSize.Channel;
imageSize.BitDepth = camConfig.ImageSize.BitDepth;
return imageSize;
}
/// <summary>
/// 이미지 크기가 동일한지 체크
/// </summary>
/// <param name="image1">이미지1</param>
/// <param name="image2">이미지2</param>
/// <returns>이미지 크기 동일 여부</returns>
public static bool ImageSizeEquals(ICogImage image1, ICogImage image2) {
var imageSize1 = GetImageSize(image1);
var imageSize2 = GetImageSize(image2);
return ImageSizeEquals(imageSize1, imageSize2);
}
/// <summary>
/// 이미지 크기가 동일한지 체크
/// </summary>
/// <param name="imageSize1">이미지 크기1</param>
/// <param name="imageSize2">이미지 크기2</param>
/// <returns>이미지 크기 동일 여부</returns>
public static bool ImageSizeEquals(ImageSize imageSize1, ImageSize imageSize2) {
if (imageSize1.Width != imageSize2.Width ||
imageSize1.Height != imageSize2.Height ||
imageSize1.BitDepth != imageSize2.BitDepth ||
imageSize1.Channel != imageSize2.Channel) {
return false;
}
return true;
}
/// <summary>
/// 이미지 크기가 null인지 체크
/// </summary>
/// <param name="imageSize">이미지 크기</param>
/// <returns>이지지 크기 null 여부</returns>
public static bool IsImageSizeNull(ImageSize imageSize) {
if (imageSize.Width == -1 && imageSize.Height == -1) {
return true;
}
else {
return false;
}
}
/// <summary>
/// 컬러 이미지인지 체크
/// </summary>
/// <param name="image">이미지</param>
/// <returns>컬러 이미지 여부</returns>
public static bool IsColorImage(ICogImage image) {
var imageSize = GetImageSize(image);
return (imageSize.Channel != 1);
}
/// <summary>
/// CogImage를 ByteArry로 변환
/// </summary>
/// <param name="image">CogImage</param>
/// <returns>ByteArry</returns>
public static byte[] ConvertCogToByteArry(ICogImage image) {
ImageSize imageSize = GetImageSize(image);
byte[] byteArry = new byte[imageSize.Width * imageSize.Height * imageSize.Channel];
//MIL.MbufGet2d(imageId, 0, 0, imageSize.Width, imageSize.Height, byteArry);
return byteArry;
}
/// <summary>
/// ByteArry를 CogImage로 변환
/// </summary>
/// <param name="byteArry">ByteArry</param>
/// <param name="width">이미지 너비</param>
/// <param name="height">이미지 높이</param>
/// <param name="image">CogImage</param>
public static void ConvertByteArryToCog(byte[] byteArry, int width, int height, ref ICogImage image) {
var imageSize = GetImageSize(image);
if (imageSize.Channel == 3) {
//MIL.MbufPutColor2d(image, MIL.M_PACKED + MIL.M_BGR24, MIL.M_ALL_BANDS, 0, 0, width, height, byteArry);
}
else {
//MIL.MbufPut2d(image, 0, 0, width, height, byteArry);
}
}
/// <summary>
/// 컬러 이미지를 흑백 이미지로 변환
/// </summary>
/// <param name="colorImage">컬러 이미지</param>
/// <returns>흑백 이미지</returns>
public static ICogImage ConvertToGray(ICogImage colorImage) {
ICogImage grayImageId = null;
ConvertToGray(colorImage, grayImageId);
return grayImageId;
}
/// <summary>
/// 컬러 이미지를 흑백 이미지로 변환
/// </summary>
/// <param name="colorImage">컬러 이미지</param>
/// <param name="grayImage">흑백 이미지</param>
/// <returns>성공 유무</returns>
public static int ConvertToGray(ICogImage colorImage, ICogImage grayImage) {
//MIL.MimConvert(colorImageId, grayImageId, MIL.M_RGB_TO_L);
return E1.OK;
}
/// <summary>
/// 흑백 이미지를 컬러 이미지로 변환
/// </summary>
/// <param name="image">흑백 이미지</param>
/// <returns>컬러 이미지</returns>
public static ICogImage ConvertGrayToRGB(ICogImage image) {
var imageSize = GetImageSize(image);
if (IsColorImage(imageSize)) {
return CloneImage(image);
}
else {
ICogImage rgbImageId = null;
//MIL.MbufAllocColor(
// Instance.GetSystem(boardSlotPos),
// 3,
// imageSize.Width,
// imageSize.Height,
// 8 + MIL.M_UNSIGNED,
// MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
// ref rgbImageId);
//MIL.MbufCopyColor(image, rgbImageId, MIL.M_RED);
//MIL.MbufCopyColor(image, rgbImageId, MIL.M_GREEN);
//MIL.MbufCopyColor(image, rgbImageId, MIL.M_BLUE);
return rgbImageId;
}
}
/// <summary>
/// 컬러 이미지인지 체크
/// </summary>
/// <param name="imageSize">이미지 크기</param>
/// <returns>컬러 이미지 여부</returns>
public static bool IsColorImage(ImageSize imageSize) {
return imageSize.Channel != 1;
}
/// <summary>
/// 이미지 클리어 (Pixel Zero)
/// </summary>
/// <param name="image">이미지</param>
/// <param name="value">RunParams.FillRegionValue</param>
public static void ClearImage(ICogImage image, int value = 0) {
if (image == null) {
return;
}
CogCopyRegionTool copyRegionTool = new CogCopyRegionTool();
copyRegionTool.InputImage = image;
copyRegionTool.DestinationImage = image;
copyRegionTool.Region = null;
copyRegionTool.RunParams.FillRegion = true;
copyRegionTool.RunParams.FillRegionValue = value;
copyRegionTool.RunParams.FillBoundingBox = false;
copyRegionTool.Run();
}
/// <summary>
/// 이미지 클리어 (Pixel Zero)
/// </summary>
/// <param name="image">이미지</param>
/// <param name="value">RunParams.FillRegionValue</param>
public static void ClearImage(object image, int value = 0) {
if (image == null) {
return;
}
CogCopyRegionTool copyRegionTool = new CogCopyRegionTool();
copyRegionTool.InputImage = (ICogImage)image;
copyRegionTool.DestinationImage = (ICogImage)image;
copyRegionTool.Region = null;
copyRegionTool.RunParams.FillRegion = true;
copyRegionTool.RunParams.FillRegionValue = value;
copyRegionTool.RunParams.FillBoundingBox = false;
copyRegionTool.Run();
}
/// <summary>
/// 자른 영역에서 픽셀 Sharpness 값 얻어오기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="cropRoi">자른 영역</param>
/// <returns>픽셀 Sharpness</returns>
public static int GetSharpnessWithCropRoi(ICogImage image, Rect cropRoi) {
ICogImage cropImage = CropImage(image, cropRoi);
return GetSharpness(cropImage);
}
/// <summary>
/// 자른 영역에서 픽셀 Sharpness 값 얻어오기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="cropRoi">자른 영역</param>
/// <returns>픽셀 Sharpness</returns>
public static int GetSharpnessWithCropRoi(ICogImage image, ROI cropRoi) {
ICogImage cropImage = CropImage(image, cropRoi);
return GetSharpness(cropImage);
}
/// <summary>
/// 픽셀 Sharpness 값 얻어오기
/// </summary>
/// <param name="image">이미지</param>
/// <returns>픽셀 Sharpness</returns>
public static int GetSharpness(ICogImage image) {
var sharpnessTool = new CogImageSharpnessTool();
int sharpness = 0;
sharpnessTool.InputImage = (CogImage8Grey)image;
sharpnessTool.RunParams.Mode = CogImageSharpnessModeConstants.BandPass;
sharpnessTool.Run();
if (sharpnessTool.RunStatus.Result == CogToolResultConstants.Accept) {
sharpness = (int)sharpnessTool.Score; // BandPass Score
}
sharpnessTool.Dispose();
return sharpness;
}
/// <summary>
/// 자른 영역에서 픽셀 밝기 정보 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="cropRoi">자른 영역</param>
/// <returns>픽셀 밝기 정보</returns>
public static BrightnessResult GetBrightnessWithCropRoi(ICogImage image, Rect cropRoi) {
ICogImage cropImage = CropImage(image, cropRoi);
return GetBrightness(cropImage, GetRectCenter(cropRoi));
}
/// <summary>
/// 자른 영역에서 픽셀 밝기 정보 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="cropRoi">자른 영역</param>
/// <returns>픽셀 밝기 정보</returns>
public static BrightnessResult GetBrightnessWithCropRoi(ICogImage image, ROI cropRoi) {
ICogImage cropImage = CropImage(image, cropRoi);
return GetBrightness(cropImage, cropRoi.Center);
}
/// <summary>
/// 픽셀 밝기 정보 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="imagePoint">ROI 중심</param>
/// <returns>픽셀 밝기 정보</returns>
public static BrightnessResult GetBrightness(ICogImage image, ImagePoint imagePoint) {
var histogramTool = new CogHistogramTool();
int min = 0;
int max = 0;
int avg = 0;
histogramTool.InputImage = (CogImage8Grey)image;
histogramTool.Run();
if (histogramTool.RunStatus.Result == CogToolResultConstants.Accept) {
min = histogramTool.Result.Minimum;
max = histogramTool.Result.Maximum;
avg = (int)histogramTool.Result.Mean;
}
histogramTool.Dispose();
return new BrightnessResult(
imagePoint,
(int)min, (int)max, (int)avg);
}
/// <summary>
/// Overlay 이미지 가져오기
/// </summary>
/// <param name="cogCameraDisplay">카메라 디스플레이</param>
/// <returns>Overlay 이미지</returns>
public static System.Drawing.Bitmap GetOverlayImage(ICogCameraDisplay cogCameraDisplay) {
var cogDisplay = cogCameraDisplay.GetDisplay();
var drawingImage = cogDisplay.CreateContentBitmap(CogDisplayContentBitmapConstants.Image);
return new System.Drawing.Bitmap(drawingImage);
}
/// <summary>
/// Overlay 이미지 저장
/// </summary>
/// <param name="filePath">파일 경로</param>
/// <param name="fovInfos">FOV 정보 리스트</param>
/// <param name="displayType">디스플레이 타입</param>
/// <param name="image">이미지</param>
/// <returns>성공 유무</returns>
public static int SaveScreenShot(string filePath, List<FovInfo> fovInfos, eDisplayType displayType, object image) {
var overlayImages = new Dictionary<FovInfo, Bitmap>();
Bitmap screenShotImage = null;
try {
foreach (var fovInfo in fovInfos) {
var cogCameraDisplay = CameraDisplayManager.GetDisplay(fovInfo, displayType) as ICogCameraDisplay;
var overlayImage = GetOverlayImage(cogCameraDisplay);
overlayImages[fovInfo] = overlayImage;
}
if (0 < overlayImages.Count) {
var screenShotImageSize = ScreenShotUtil.GetScreenShotImageSize(overlayImages, displayType);
if (screenShotImageSize == null) {
return E1.GENERIC;
}
screenShotImage = new Bitmap(screenShotImageSize.Width, screenShotImageSize.Height);
var (ltFovInfo, ltFovUiPos) = ScreenShotUtil.GetLeftTopFovInfo(overlayImages.Keys.ToList(), displayType);
var (ltFovUiPosRow, ltFovUiPosCol) = FovRecipe.GetFovUiPosRowCol(ltFovUiPos);
foreach (var fovInfo in fovInfos) {
var fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo);
eFovUiPos fovUiPos = new eFovUiPos();
foreach (var mainUiRecipe in fovRecipe.MainUiRecipes) {
if (mainUiRecipe.MainDisplayType == displayType) {
fovUiPos = mainUiRecipe.FovUiPos;
}
}
var (curFovUiPosRow, curFovUiPosCol) = FovRecipe.GetFovUiPosRowCol(fovUiPos);
ScreenShotUtil.MergeImages(
overlayImages[fovInfo],
screenShotImage,
(curFovUiPosCol - ltFovUiPosCol) * overlayImages[fovInfo].Width,
(curFovUiPosRow - ltFovUiPosRow) * overlayImages[fovInfo].Height);
}
SaveImage(filePath, screenShotImage);
}
}
catch (Exception e) {
_Logger.E(e.Message);
}
finally {
screenShotImage?.Dispose();
foreach (var overlayImage in overlayImages.Values) {
overlayImage?.Dispose();
}
}
return E1.OK;
}
/// <summary>
/// 사각 영역(Rect)을 CogRectangle로 변환
/// </summary>
/// <param name="rect">사각 영역</param>
/// <returns>CogRectangle</returns>
public static CogRectangle ConvertToCogRectangle(Rect rect) {
try {
var cogRectangle = new CogRectangle();
cogRectangle.SetXYWidthHeight(
rect.X,
rect.Y,
rect.Width,
rect.Height);
return cogRectangle;
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return null;
}
/// <summary>
/// 사각 영역(ROI)을 CogRectangle로 변환
/// </summary>
/// <param name="roi">사각 영역</param>
/// <returns>CogRectangle</returns>
public static CogRectangle ConvertToCogRectangle(ROI roi) {
try {
var cogRectangle = new CogRectangle();
cogRectangle.SetCenterWidthHeight(
roi.CenterX,
roi.CenterY,
roi.Width,
roi.Height);
return cogRectangle;
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return null;
}
/// <summary>
/// 사각 영역(ROI)을 CogRectangleAffine으로 변환
/// </summary>
/// <param name="roi">사각 영역</param>
/// <returns>CogRectangleAffine</returns>
public static CogRectangleAffine ConvertToCogRectangleAffine(ROI roi) {
try {
var cogRectangleAffine = new CogRectangleAffine();
cogRectangleAffine.SetCenterLengthsRotationSkew(
roi.CenterX, roi.CenterY, roi.Width, roi.Height, roi.Angle.Radian, 0);
return cogRectangleAffine;
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return new CogRectangleAffine();
}
/// <summary>
/// CogRectangle을 사각 영역(ROI)으로 변환
/// </summary>
/// <param name="cogRectangle">CogRectangle</param>
/// <returns>사각 영역(ROI)</returns>
public static ROI ConvertToRoi(CogRectangle cogRectangle) {
try {
var roi = new ROI(
(int)cogRectangle.X,
(int)cogRectangle.Y,
(int)cogRectangle.Width,
(int)cogRectangle.Height);
return roi;
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return new ROI();
}
/// <summary>
/// CogRectangleAffine을 사각 영역(ROI)으로 변환
/// </summary>
/// <param name="cogRectangleAffine">CogRectangleAffine</param>
/// <returns>사각 영역(ROI)</returns>
public static ROI ConvertToRoi(CogRectangleAffine cogRectangleAffine) {
try {
var angle = new Angle() {
Radian = cogRectangleAffine.Rotation,
Degree = CogMisc.RadToDeg(cogRectangleAffine.Rotation)
};
var roi = new ROI(
cogRectangleAffine.CenterX,
cogRectangleAffine.CenterY,
(int)cogRectangleAffine.SideXLength,
(int)cogRectangleAffine.SideYLength,
angle);
return roi;
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return new ROI();
}
/// <summary>
/// CogRectangleAffine 영역 X,Y 픽셀 이동
/// </summary>
/// <param name="region">CogRectangleAffine</param>
/// <param name="translationX">픽셀 이동량X</param>
/// <param name="translationY">픽셀 이동량Y</param>
/// <returns>CogRectangleAffine</returns>
public static CogRectangleAffine Translate(CogRectangleAffine region, double translationX, double translationY) {
try {
var translatedRegion = new CogRectangleAffine();
translatedRegion.SetOriginCornerXCornerY(
region.CornerOriginX + translationX,
region.CornerOriginY + translationY,
region.CornerXX + translationX,
region.CornerXY + translationY,
region.CornerYX + translationX,
region.CornerYY + translationY);
return translatedRegion;
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return null;
}
/// <summary>
/// 소수점 단위인 Cog 스코어를 백분율(%) 단위로 변환
/// </summary>
/// <param name="cogScore">Cog 스코어</param>
/// <returns>스코어(%)</returns>
public static double ConvertToVisionScore(double cogScore) {
return cogScore * 100;
}
/// <summary>
/// 백분율(%) 단위인 스코어를 소수점 단위인 Cog 스코어로 변환
/// </summary>
/// <param name="visionScore">스코어(%)</param>
/// <returns>Cog 스코어</returns>
public static double ConvertToCogScore(double visionScore) {
return visionScore / 100;
}
/// <summary>
/// 소수점 단위인 scale을 백분율(%) 단위로 변환
/// </summary>
/// <param name="scale">스케일</param>
/// <returns>Certainty(%)</returns>
public static double ConvertToCertainty(double scale) {
return scale * 100;
}
/// <summary>
/// 백분율(%) 단위인 certainty를 소수점 단위로 변환
/// </summary>
/// <param name="certainty">Certainty(%)</param>
/// <returns>스케일</returns>
public static double ConvertToScale(double certainty) {
return certainty / 100;
}
}
}