zl程序教程

您现在的位置是:首页 >  其它

当前栏目

Halcon MapImage 复刻 remap

HALCON 复刻 remap
2023-06-13 09:18:40 时间

之前介绍了 OpenCV 的 remap 函数,Halcon 中也有类似函数 MapImage,本文介绍 MapImage,并将 OpenCV 的 remap 转换为 MapImage。

map_image

  • 函数使用
map_image(Image, Map : ImageMapped : : )
  • 其中:
    • Image: 需要被映射修改的图像
    • Map: 映射矩阵
    • ImageMapped: 映射结果
  • 可以看到核心在于 Map 矩阵如何定义和使用。
  • Map 为和原始图像一样大小的 5 通道图像,第一个通道格式为 32 bits 深度int4 类型,表示的是每个需要被映射的图像像素位置对应的原始图像像素编号

这是一张宽度 3072 的图像的映射示例,每个像素的值表示的是原始图像的像素编号

  • Map 的第2-5个通道的格式为 16 bits 的 uint2 类型,表示的是插值四个像素的占比,第一个通道指向的是四个相邻像素中左上角的一个
  • 后四个通道指向的分别是四个比例:
  • uint2 表示比例的思路是四个数的和是 65535(可能会有1-2的误差),根据数值占 65535 的比例来决定四个像素的插值比例
  • 每个通道的图像都看起来挺神奇的,这里展示一张示例图像

remap -> map_image

  • OpenCV 的 remap 需要两个 map 作为输入,可以在 C++ 中将这两个 map 转为 halcon 的 map
Mat map1, map2, R;
initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newcameramatrix, imageSize, CV_32FC1, map1, map2);
Mat main_map, sub_map2, sub_map3, sub_map4, sub_map5;
main_map = main_map.zeros(imageSize, CV_32S);
sub_map2 = sub_map2.zeros(imageSize, CV_16U);
sub_map3 = sub_map3.zeros(imageSize, CV_16U);
sub_map4 = sub_map4.zeros(imageSize, CV_16U);
sub_map5 = sub_map5.zeros(imageSize, CV_16U);
float x_value, y_value;
float x_diff, y_diff;
int x_temp, y_temp;
for (introw(0); row < imageSize.height; row++) {
for (intcol(0); col < imageSize.width; col++) {
		x_value = map1.at<float>(row, col);
		y_value = map2.at<float>(row, col);
		x_temp = floor(x_value);
		y_temp = floor(y_value);
if (x_value < 0or y_value < 0)
		{
			main_map.at<int32_t>(row, col) = 0;
			sub_map2.at<uint16_t>(row, col) = 0;
			sub_map3.at<uint16_t>(row, col) = 0;
			sub_map4.at<uint16_t>(row, col) = 0;
			sub_map5.at<uint16_t>(row, col) = 0;
		}
else
		{
			x_diff = x_value - x_temp;
			y_diff = y_value - y_temp;
			main_map.at<int32_t>(row, col) = y_temp * imageSize.width + x_temp;
			sub_map2.at<uint16_t>(row, col) = (1 - x_diff) * (1 - y_diff) * 65535;
			sub_map3.at<uint16_t>(row, col) = x_diff * (1 - y_diff) * 65535;
			sub_map4.at<uint16_t>(row, col) = (1 - x_diff) * y_diff * 65535;
			sub_map5.at<uint16_t>(row, col) = x_diff * y_diff * 65535;
		}
	}
}
HalconCpp::HImage main_data, sub_map_data2, sub_map_data3, sub_map_data4, sub_map_data5;
int height1 = main_map.rows, width1 = main_map.cols;
int size = height1 * width1;
uchar *temp = new uchar[size * 4];
memcpy(temp, main_map.data, size * 4);
HalconCpp::GenImage1(&main_data, "int4", imageSize.width, imageSize.height, (Hlong)(temp));
memcpy(temp, sub_map2.data, size * 2);
HalconCpp::GenImage1(&sub_map_data2, "uint2", imageSize.width, imageSize.height, (Hlong)(temp));
memcpy(temp, sub_map3.data, size * 2);
HalconCpp::GenImage1(&sub_map_data3, "uint2", imageSize.width, imageSize.height, (Hlong)(temp));
memcpy(temp, sub_map4.data, size * 2);
HalconCpp::GenImage1(&sub_map_data4, "uint2", imageSize.width, imageSize.height, (Hlong)(temp));
memcpy(temp, sub_map5.data, size * 2);
HalconCpp::GenImage1(&sub_map_data5, "uint2", imageSize.width, imageSize.height, (Hlong)(temp));
delete[] temp;
HalconCpp::HImage map_h, map_res_h;
Compose5(main_data, sub_map_data2, sub_map_data3, sub_map_data4, sub_map_data5, &map_h);
MapImage(ImageGray, map_h, &map_res_h); 

参考资料