Add support to IMAQ conversion
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "ANSOpenCV.h"
|
||||
#include "ANSMatRegistry.h"
|
||||
#include <nivision.h>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <json.hpp>
|
||||
@@ -5103,4 +5104,131 @@ extern "C" __declspec(dllexport) int ANSCV_AddSpeckleNoise_V2(uint64_t handleVal
|
||||
else return 0;
|
||||
}
|
||||
catch (...) { return -1; }
|
||||
}
|
||||
|
||||
// ── IMAQ <-> cv::Mat conversion ──────────────────────────────────
|
||||
|
||||
extern "C" __declspec(dllexport) int ANSCV_IMAQ2Image(Image* imaqImage, cv::Mat** imageOut) {
|
||||
try {
|
||||
if (!imaqImage || !imageOut) return -2;
|
||||
|
||||
ImageInfo info;
|
||||
if (!imaqGetImageInfo(imaqImage, &info)) return -4;
|
||||
if (!info.imageStart || info.xRes <= 0 || info.yRes <= 0) return -2;
|
||||
|
||||
int width = info.xRes;
|
||||
int height = info.yRes;
|
||||
int stride = info.pixelsPerLine; // pixels per row (may include padding)
|
||||
|
||||
cv::Mat result;
|
||||
switch (info.imageType) {
|
||||
case IMAQ_IMAGE_U8: {
|
||||
// 8-bit grayscale: stride is in pixels = bytes
|
||||
cv::Mat wrapper(height, width, CV_8UC1, info.imageStart, stride * sizeof(unsigned char));
|
||||
result = wrapper.clone();
|
||||
break;
|
||||
}
|
||||
case IMAQ_IMAGE_U16: {
|
||||
// 16-bit grayscale
|
||||
cv::Mat wrapper(height, width, CV_16UC1, info.imageStart, stride * sizeof(unsigned short));
|
||||
result = wrapper.clone();
|
||||
break;
|
||||
}
|
||||
case IMAQ_IMAGE_RGB: {
|
||||
// IMAQ RGB is 32-bit RGBX (RGBValue: B,G,R,alpha) — same layout as BGRA
|
||||
cv::Mat bgra(height, width, CV_8UC4, info.imageStart, stride * sizeof(RGBValue));
|
||||
cv::cvtColor(bgra, result, cv::COLOR_BGRA2BGR);
|
||||
break;
|
||||
}
|
||||
case IMAQ_IMAGE_SGL: {
|
||||
// 32-bit float grayscale
|
||||
cv::Mat wrapper(height, width, CV_32FC1, info.imageStart, stride * sizeof(float));
|
||||
result = wrapper.clone();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -5; // Unsupported image type
|
||||
}
|
||||
|
||||
*imageOut = anscv_mat_new(result);
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Error in ANSCV_IMAQ2Image: " << e.what() << std::endl;
|
||||
return -3;
|
||||
}
|
||||
catch (...) { return -1; }
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) int ANSCV_Image2IMAQ(cv::Mat** imageIn, Image* imaqImage) {
|
||||
try {
|
||||
if (!imageIn || !(*imageIn) || (*imageIn)->empty() || !imaqImage) return -2;
|
||||
|
||||
const cv::Mat& mat = **imageIn;
|
||||
int width = mat.cols;
|
||||
int height = mat.rows;
|
||||
|
||||
// Set the IMAQ image size (allocates pixel buffer)
|
||||
if (!imaqSetImageSize(imaqImage, width, height)) return -4;
|
||||
|
||||
ImageInfo info;
|
||||
if (!imaqGetImageInfo(imaqImage, &info)) return -4;
|
||||
if (!info.imageStart) return -4;
|
||||
|
||||
int dstStride = info.pixelsPerLine;
|
||||
|
||||
switch (mat.type()) {
|
||||
case CV_8UC1: {
|
||||
// Grayscale -> IMAQ_IMAGE_U8
|
||||
for (int y = 0; y < height; y++) {
|
||||
memcpy(static_cast<unsigned char*>(info.imageStart) + y * dstStride,
|
||||
mat.ptr<unsigned char>(y), width * sizeof(unsigned char));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CV_16UC1: {
|
||||
// 16-bit grayscale -> IMAQ_IMAGE_U16
|
||||
for (int y = 0; y < height; y++) {
|
||||
memcpy(static_cast<unsigned char*>(info.imageStart) + y * dstStride * sizeof(unsigned short),
|
||||
mat.ptr<unsigned short>(y), width * sizeof(unsigned short));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CV_8UC3: {
|
||||
// BGR -> IMAQ_IMAGE_RGB (BGRA with alpha=0)
|
||||
cv::Mat bgra;
|
||||
cv::cvtColor(mat, bgra, cv::COLOR_BGR2BGRA);
|
||||
for (int y = 0; y < height; y++) {
|
||||
memcpy(static_cast<unsigned char*>(info.imageStart) + y * dstStride * sizeof(RGBValue),
|
||||
bgra.ptr<unsigned char>(y), width * sizeof(RGBValue));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CV_8UC4: {
|
||||
// BGRA -> IMAQ_IMAGE_RGB directly
|
||||
for (int y = 0; y < height; y++) {
|
||||
memcpy(static_cast<unsigned char*>(info.imageStart) + y * dstStride * sizeof(RGBValue),
|
||||
mat.ptr<unsigned char>(y), width * sizeof(RGBValue));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CV_32FC1: {
|
||||
// Float -> IMAQ_IMAGE_SGL
|
||||
for (int y = 0; y < height; y++) {
|
||||
memcpy(static_cast<unsigned char*>(info.imageStart) + y * dstStride * sizeof(float),
|
||||
mat.ptr<float>(y), width * sizeof(float));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -5; // Unsupported cv::Mat type
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Error in ANSCV_Image2IMAQ: " << e.what() << std::endl;
|
||||
return -3;
|
||||
}
|
||||
catch (...) { return -1; }
|
||||
}
|
||||
@@ -7,6 +7,12 @@
|
||||
#include <vector>
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
// Forward declaration for NI Vision IMAQ Image (avoids nivision.h dependency for consumers)
|
||||
#ifndef NI_IMAGE_TYPE_DEF
|
||||
#define NI_IMAGE_TYPE_DEF
|
||||
typedef struct Image_struct Image;
|
||||
#endif
|
||||
|
||||
#define MUTEX_TIMEOUT_MS 45000
|
||||
namespace fs = std::filesystem;
|
||||
namespace ANSCENTER
|
||||
@@ -161,4 +167,8 @@ extern "C" __declspec(dllexport) int ANSCV_ImagePatternMatchs_S(cv::Mat** image
|
||||
|
||||
extern "C" __declspec(dllexport) int ANSCV_ImagesToMP4_S(const char* imageFolder, const char* outputVideoPath, int targetDurationSec);
|
||||
|
||||
// IMAQ <-> cv::Mat conversion functions
|
||||
extern "C" __declspec(dllexport) int ANSCV_IMAQ2Image(Image* imaqImage, cv::Mat** imageOut);
|
||||
extern "C" __declspec(dllexport) int ANSCV_Image2IMAQ(cv::Mat** imageIn, Image* imaqImage);
|
||||
|
||||
#endif
|
||||
@@ -45,6 +45,15 @@ target_include_directories(ANSCV PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
# NI Vision (IMAQ) support
|
||||
target_include_directories(ANSCV PRIVATE
|
||||
"C:/Program Files (x86)/National Instruments/Shared/ExternalCompilerSupport/C/include"
|
||||
)
|
||||
target_link_directories(ANSCV PRIVATE
|
||||
"C:/Program Files (x86)/National Instruments/Shared/ExternalCompilerSupport/C/lib64/msvc"
|
||||
)
|
||||
target_link_libraries(ANSCV PRIVATE nivision)
|
||||
|
||||
# MediaClient includes (referenced from original ANLS)
|
||||
target_include_directories(ANSCV PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/MediaClient
|
||||
|
||||
Reference in New Issue
Block a user