- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试检测闪烁像素。我先用 C++ 编写了代码,但我意识到 CPU 不适合它。所以我找到了 OpenCL 库。我以前从未使用过它。此外,我还没有找到适合 OpenCL 的文档。
OpenCLHelper.cpp
#include <CL/cl.hpp>
#include <fstream>
#include <iostream>
#include <stdlib.h>
cl::Program CreateProgram(const std::string& fileName) {
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
auto platform = platforms.front();
std::vector<cl::Device> devices;
platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
auto device = devices.front();
std::ifstream file(fileName);
std::string src(std::istreambuf_iterator<char>(file), (std::istreambuf_iterator<char>()));
cl::Program::Sources sources(1, std::make_pair(src.c_str(), src.length()+1));
cl::Context context(device);
cl::Program program(context, sources);
std::cout << program.build("-cl-std=CL1.2") << std::endl;
return program;
}
main.cpp(不是文件的全部代码)
cl::Context context = program.getInfo<CL_PROGRAM_CONTEXT>();
vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
cl::Device device = devices.front();
unsigned char* shootFrame(unsigned char *data) {
unsigned char* frequencyImage = new unsigned char[pixelsPerFrame];
strcopy(data, frequencyImage);
cl_int err = 0;
cl::Buffer inBuf(context, CL_MEM_READ_ONLY | CL_MEM_HOST_NO_ACCESS | CL_MEM_COPY_HOST_PTR, sizeof(unsigned char) * pixelsPerFrame * equalxFramesAtTheSameTime, lastFrames, &err);
cout << err << endl;
cl::Buffer outBuf(context, CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(unsigned char) * pixelsPerFrame, nullptr, &err);
cl::Buffer var1(context, CL_MEM_READ_ONLY | CL_MEM_HOST_NO_ACCESS | CL_MEM_COPY_HOST_PTR, sizeof(int), &isLightOn, &err);cout << err << endl;
//I creates variables, because I can't use #define in there
int equalxFramesAtTheSameTime2 = equalxFramesAtTheSameTime;
cl::Buffer var2(context, CL_MEM_READ_ONLY | CL_MEM_HOST_NO_ACCESS | CL_MEM_COPY_HOST_PTR, sizeof(int), &equalxFramesAtTheSameTime2, &err);cout << err << endl;
int thresholdPixel2 = thresholdPixel;
cl::Buffer var3(context, CL_MEM_READ_ONLY | CL_MEM_HOST_NO_ACCESS | CL_MEM_COPY_HOST_PTR, sizeof(int), &thresholdPixel2, &err);cout << err << endl;
int ppf = pixelsPerFrame;
cl::Buffer var4(context, CL_MEM_READ_ONLY | CL_MEM_HOST_NO_ACCESS | CL_MEM_COPY_HOST_PTR, sizeof(int), &ppf, &err);cout << err << endl;
cl::Buffer var5(context, CL_MEM_READ_ONLY | CL_MEM_HOST_NO_ACCESS | CL_MEM_COPY_HOST_PTR, sizeof(int), ¤tFrameID, &err);cout << err << endl;
cl::Kernel kernel(program, "ProcessImage"); cout << err << endl;
err = kernel.setArg(0, var1); cout << err << endl;
err = kernel.setArg(1, var2); cout << err << endl;
err = kernel.setArg(2, var3); cout << err << endl;
err = kernel.setArg(3, var4); cout << err << endl;
err = kernel.setArg(4, var5); cout << err << endl;
err = kernel.setArg(5, inBuf); cout << err << endl;
err = kernel.setArg(6, outBuf); cout << err << endl;
cl::CommandQueue queue(context, device);
err = queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(pixelsPerFrame)); cout << err << endl;
err = queue.enqueueReadBuffer(outBuf, CL_FALSE, 0, sizeof(unsigned char) * pixelsPerFrame, done); cout << err << endl;
cout << "done: " << queue.finish() << endl;
return getXYfromRawImage(done, frequencyImage, updown, leftright);
}
ProcessImage.cl
__kernel void ProcessImage(const int isLightOn, const int frameSize, const int thresholdPixel, const int pixelsPerFrame, const int currentFrameID, __global unsigned char* lastFrames, __global unsigned char* outData) {
int isBegin = 1;
bool mustBrightNow = !isLightOn;
int lastPixel = 0;
int isWrongPixel = 0;
for (int i=currentFrameID; i<frameSize + currentFrameID; i++) {
int i2 = i;
if(i >= frameSize) {
i2 = i2 - frameSize;
}
int id = (i2 * pixelsPerFrame) + get_global_id(0);
if (isBegin == 1) {
lastPixel = (int) lastFrames[ id ];
isBegin = 0;
} else {
int currentPixel = (int) lastFrames[ id ];
if (mustBrightNow == false) {
if (currentPixel + thresholdPixel < lastPixel) {
mustBrightNow = true;
} else {
isWrongPixel = 0; //It freezes when I write '1'
instead of '0'
break;
}
} else {
if (currentPixel - thresholdPixel > lastPixel) {
mustBrightNow = false;
} else {
isWrongPixel = 0; //Also it freezes when I write '1'. And it doesn't matter if is an integer or a boolean.
break;
}
}
lastPixel = currentPixel;
}
}
if (isWrongPixel == 0) {
outData[get_global_id(0)] = (uchar) (0);
} else {
outData[get_global_id(0)] = (uchar) (1);
}
}
在所有 cout
上,我得到 0
。所以“没有”明显的错误。
我知道,代码的某些部分没有优化,但它应该可以工作。
如果您现在想要,unsigned char* lastFrames
就像每个像素一个字符(单色)一样构建。所以它的大小是 2000 万(宽 x 高 x 前几帧)。所以它有多个帧,我可以在 OpenCL 中比较不同的帧。
那会是什么?
isWrongPixel
1
或真
。0
或 false
时它会起作用,但我需要一个 bool 值。那我做错了什么?
我知道我的语法不完全正确..
提前致谢
最佳答案
根据评论的讨论。
这是一个如何使用图片的例子:
#include <CL/cl.hpp>
#include <vector>
std::vector<cl::Platform> clPlatforms;
cl::Platform::get(&clPlatforms);
// TODO Set correctly
cl::Device chosenDevice;
bool first = true;
for (auto &&platform : clPlatforms) {
std::vector<cl::Device> clDevices;
platform.getDevices(CL_DEVICE_TYPE_ALL, &clDevices);
if (first) { // REMOVE
chosenDevice = clDevices[0];
first = false;
}
std::cout << platform.getInfo<CL_PLATFORM_NAME>()<<'\n';
for (auto &&device : clDevices) {
std::cout << device.getInfo<CL_DEVICE_NAME>()<<'\n';
}
}
cl::Context context{chosenDevice};
// Possible values
// https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/cl_image_format.html
cl::ImageFormat format{ CL_R, CL_UNSIGNED_INT8};
std::size_t imageWidth = 640;
std::size_t imageHeight = 480;
std::size_t numFrames = 128;
// Fill as sequences of rows for each 2D
std::uint8_t
*input = new std::uint8_t[imageWidth * imageHeight * numFrames];
std::size_t i = 0;
for (std::size_t frameI = 0; frameI < numFrames; ++frameI)
for (std::size_t y = 0; y < imageHeight; ++y)
for (std::size_t x = 0; x < imageWidth; ++x)
input[i++] = 0; // INIT
// Zeroes specify data format, see
// https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/clCreateImage3D.html
// Note that images cannot be both read and write
cl::Image3D
inImage{context,
CL_MEM_READ_ONLY | CL_MEM_HOST_NO_ACCESS | CL_MEM_COPY_HOST_PTR,
format,
imageWidth,
imageHeight,
numFrames,
0,
0,
input,
nullptr};
cl::Image2D outImage{context, CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY,
format, imageWidth, imageHeight};
std::string source = "PASTE SOURCE HERE";
cl::Program program(context, source);
program.build("-cl-std=CL1.2");
cl::Kernel kernel(program, "ProcessImage");
kernel.setArg(0, (int)0);
kernel.setArg(1, (int)numFrames);
int thresholdPixel = 10; // SET
kernel.setArg(2, (int)thresholdPixel);
kernel.setArg(3, (int)(imageWidth * imageHeight));
int currentFrameID = 12; // SET
kernel.setArg(4, (int)currentFrameID);
kernel.setArg(5, inImage);
kernel.setArg(6, outImage);
cl::CommandQueue queue(context, chosenDevice);
queue.enqueueNDRangeKernel(kernel, cl::NullRange,
cl::NDRange(imageWidth, imageHeight));
std::uint8_t *output = new std::uint8_t[imageWidth * imageHeight];
// See
// https://www.khronos.org/registry/OpenCL/sdk/1.0/docs/man/xhtml/clEnqueueReadImage.html
cl::size_t<3> region;
region[0] = imageWidth;
region[1] = imageHeight;
region[2] = 1;
//Might as well block if the next call would be clFinish anyway.
queue.enqueueReadImage(outImage, true, cl::size_t<3>(), region, 0, 0,
output);
内核源码:
__kernel void ProcessImage(const int isLightOn, const int frameSize, const int thresholdPixel, const int pixelsPerFrame, const int currentFrameID, read_only image3d_t lastFrames, write_only image2d_t outData) {
int isBegin = 1;
bool mustBrightNow = !isLightOn;
int lastPixel = 0;
int isWrongPixel = 0;
for (int i=currentFrameID; i<frameSize + currentFrameID; i++) {
int i2 = i;
if(i >= frameSize) {
i2 = i2 - frameSize;
}
int pixValue = (int)read_imageui(lastFrames,(int4)(get_global_id(0),get_global_id(1),i2,0)).x;
if (isBegin == 1) {
lastPixel = pixValue;
isBegin = 0;
} else {
int currentPixel = pixValue;
if (mustBrightNow == false) {
if (currentPixel + thresholdPixel < lastPixel) {
mustBrightNow = true;
} else {
isWrongPixel = 1;
break;
}
} else {
if (currentPixel - thresholdPixel > lastPixel) {
mustBrightNow = false;
} else {
isWrongPixel = 1;
break;
}
}
lastPixel = currentPixel;
}
}
write_imageui(outData,(int2)(get_global_id(0),get_global_id(1)),(uint4)(isWrongPixel,0,0,0));
}
我能够在我的 1050TI、Intel 7700HQ 和 Intel 630HD 上运行这段代码而不会卡机,我希望你会:)
我用图像替换了缓冲区,并将此任务设为“2D”,这反射(reflect)在 enqueueNDRangeKernel
中。内核做完全相同的事情,但它使索引图像更加自然。我不确定您是否知道可能允许您使用 GPU 的多个平台。它只需要最新的驱动程序,就可以在平台和设备中显示。无需为 const
变量创建缓冲区,只需在 kernel.setArg
模板函数中使用正确的类型即可。
所以试试吧:)
关于c++ - 如何修复 OpenCL 卡住?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55359955/
我将一个 div 设置为 100% 宽度,当以 1024 分辨率查看页面时,宽度应从 100% 变为 1000px,我让它与@media 查询一起正常工作,并且在 FF、safari chrome 上
希望有人能帮助我,我已经被困了几天了。 将我的 Domino 服务器更新到 9.01 Fix 3 后,我在 javascript 控制台上不断收到错误消息: TypeError: this.edito
我们正在使用一个基于RMI的java应用程序。当我们运行应用程序时,即使应用程序处于理想阶段,内存使用量仍然不断增加。我们主要使用Vector和散列图数据结构。如何最大限度地减少java内存使用/修复
概述 Internet Download Manager (IDM)是最流行的 Windows 下载管理器。如果你平时工作中使用过IDM,您会惊叹 IDM 下载文件的速度有多快。IDM
当我打开 brave 浏览器时,会打开一个窗口(如下所示)。它并没有真正干扰浏览器的处理。但令人担忧的是为什么这种情况一直发生...... Error On Opening Brave Browser
这是我今天在求职面试中被问到的一个问题: 看下面的代码: int n=20; for (int i =0; i
我不小心删除了/opt/local/bin/perl5.8.9 ,这似乎是 macports 编译的 perl 的主要二进制文件。 现在我有很多取决于 perl5 的端口,但不想卸载并重新安装所有端口
>>>flip fix (0 :: Int) (\a b -> putStrLn "abc") Output: "abc" 这是使用翻转修复的简化版本。 我在一些 YouTube 视频中看到了这种使用
这个问题已经有答案了: How can I fix 'android.os.NetworkOnMainThreadException'? (64 个回答) 已关闭 3 年前。 我在 Android 应
def main(): cash = float(input("How much money: ")) coins = 0 def changeCounter(n): whil
前一周我遇到了类似的问题,查询需要永远运行。在编写此查询时,我尝试应用从其他查询中学到的一些知识,但执行起来需要很长时间。 运行查询的两个单独部分时,每个部分需要 2 分钟才能完成,这是可以接受的,但
下午,我的 CSS 有问题。第三个下拉菜单放错了,我没有解决办法。 这是我想要的: 之前: http://i53.tinypic.com/2qu85z8.png 之后: http://i51.tiny
更新方法: override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingS
我知道这是一个很多人都遇到过的问题,但我不熟悉 Less 并且是 Bootstrap 的新手,我正在寻找一种全 CSS 解决方案来防止我的导航栏折叠到 768 像素以下:
在我的布局中,我创建了以下 jsfiddle 托管的可调整大小的粘性页脚。但是,在调整大小时它与内容重叠。有没有办法让它在所有浏览器上都能响应? http://jsfiddle.net/9aLc0mg
我想要实现的目标 racer-offset 是为了让用户可以设置图像可以以 px 为单位移动多远。偏移量管理偏移量。 Speed-racer 告诉我们图像在滚动过程中移动的速度。我的问题是它不会停止。
我有一个简单的自动换行函数,它接受一个长字符串作为输入,然后将该字符串分成更小的字符串,并将它们添加到一个数组中,以便稍后输出。现在最后一两个字没有输出。这是主要问题。但是,我还想改进功能。我知道这有
我试图在使用每个 slider 之前禁用“下一步”按钮,我不确定为什么在单击不再是 class="not-clicked"的同一个 slider 时取消禁用该按钮. JSFiddle: (这里看起来有
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 8 年前。 如何让程序输出所有信息? IT
On this page ,在“生活”下有一个带有自动生成的子菜单的菜单。子菜单存在一些问题(它会闪烁并改变大小——如果你滚动它就会看到)。我需要以某种方式覆盖它当前正在读取的 css 并使其统一。
我是一名优秀的程序员,十分优秀!