image - 使用 64 位操作在 openCV 中每次读/写访问多个像素
问题描述
我是openCV的新手。我正在编辑图像,需要在图像的大矩形块上读取和写入连续像素,而不是整个图像。我的输入图像是单通道灰度,CV_16UC1 作为输入,CV_8UC1 作为输出。我目前正在使用 MatConstIterator_ 访问像素。
Mat image, image_read = imread(infilename, 0);
image_read.convertTo(image, CV_16UC1);
//...define img_dim_y, img_dim_x
Mat imout(img_dim_y, img_dim_x, CV_8UC1);
MatConstIterator_<uint16_t> pin = imageIn.begin<uint16_t>(), pixel_in_end = imageIn.end<uint16_t>();
MatIterator_<uint8_t> pixel_out = imageOut.begin<uint8_t>();
for(; /*selected pixel in a patch*/; ++pixel_out , ++pixel_out)
*pixel_out = My_transform(*pixel_in);
这是内存带宽有限的,并且所有时间都以每像素 10 微秒的速率读取和写入像素。我的机器非常现代,所以这比 ~MHz ram 时钟慢得多。对于 64 位机器,应该可以一次读入 4 个 16 位像素,一次写出 8 个 8 位像素,使用几个移位操作。这将使流水线速度至少提高 4-5 倍。如何哄骗这些数据进出 openCV Mat?
解决方案
我找到了一种方法来做这样的事情。以下将一次读取 4 个像素,但在读取一小部分图像后,它会在随机位置出现段错误。
//For a Mat img formatted as a CV_16UC1
uint8_t* alignas(64) Data = (uint8_t*)img.data;
for(int i = 0; /*selected pixel in a patch*/; i += 8){
uint16_t p0, p1, p2, p3; //pixels
uint64_t word = reinterpret_cast<uint64_t*>(Data)[i];
p0 = (word & 0x00000000000000FF) + ((word & 0x000000000000FF00) >> 8);
p1 = ((word & 0x0000000000FF0000) >> 16) + ((word & 0x00000000FF000000) >> 24);
p2 = ((word & 0x000000FF00000000) >> 32) + ((word & 0x0000FF0000000000) >> 40);
p3 = ((word & 0x00FF000000000000) >> 48) + ((word & 0xFF00000000000000) >> 56);
//do things with pixels
}
推荐阅读
- android - 两个标签及其在 Android 自定义键盘上的点击操作
- laravel - Laravel api注销用户不活动
- c# - 当您在 DI 中手动执行实例时,如何提供 IServiceProvider 作为依赖项?
- php - 如何在隐藏字段上选择 Typeform API?
- javascript - 如何为 wordpress 网站制作粘性侧边栏?
- jquery - Jquery val() 编号不正确?
- angular - Angular ng-pick-datetime 使输入字段不可见
- c - 可以在 C 中的函数调用的参数之间放置注释吗?
- javascript - 如何获取基于文本框实时更改的图像链接?
- python - Python 中的 Pyo:未定义名称“服务器”