- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am using dpc++ compiler integrated with microsoft visual studio, I wrote a small app to apply a filter to an image (gray scale), the app will compute the new value of the pixel on the device and store it on new filtered_image_buffer, while computing, the value is float and then it will be converted to uchar but the behavior is different when I use cpu vs gpu selector, on gpu the filter is applied correctly and the result image is fine, but in cpu the image is in chaos.
cpu that I am using: Intel(R) Core(TM) i7-8665U
gpu: Intel(R) UHD Graphics 620
here the results for gpu vs cpu (filter to sharpen the image is used)
code:
```
#include <sycl/sycl.hpp>
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace sycl;
int main(int argc, char* argv[]) {
cv::Mat image = cv::imread("oneapi1.png", cv::IMREAD_GRAYSCALE);
if (image.empty()) {
std::cout << "Could not open or find the image" << std::endl;
return -1;
}
std::vector<uchar> imageData;
imageData.assign(image.data, image.data + image.total());
buffer <uchar, 1> imageBuffer(imageData.data(), range<1>(image.total()));
cv::Mat filteredImage = image.clone();
std::vector<uchar> filteredImageData;
filteredImageData.assign(filteredImage.data, filteredImage.data + filteredImage.total() * filteredImage.channels());
cpu_selector selector;
queue q{ selector };
auto height = image.rows;
auto width = image.cols;
const int filterHeight = 5;
const int filterWidth = 5;
float filter[filterHeight][filterWidth] = {
{-1, -1, -1, -1, -1,},
{-1, 1.5, 1.5, 1.5, -1},
{-1, 1.5, 5, 1.5, -1},
{-1, 1.5, 1.5, 1.5, -1},
{-1, -1, -1, -1, -1}
};
buffer <float, 2> filterBuf(range<2>(filterHeight, filterWidth));
{
auto filterBufAcc = filterBuf.get_access<access::mode::read_write>();
for (int i = 0; i < filterHeight; i++) {
for (int j = 0; j < filterWidth; j++) {
filterBufAcc[i][j] = filter[i][j];
}
}
}
{
buffer <uchar, 1> filteredImageBuffer(filteredImageData.data(), range<1>(filteredImage.total() * filteredImage.channels()));
q.submit([&](handler& h) {
auto imageAcc = imageBuffer.get_access<access::mode::read>(h);
auto filteredImageAcc = filteredImageBuffer.get_access<>(h);
auto filterAcc = filterBuf.get_access<access::mode::read>(h);
h.parallel_for(range<2>{height - ((filterHeight / 2) * 2), width - ((filterWidth / 2) * 2)}, [=](item<2> id) {
float value = 0;
auto global_row = id.get_id(0) + (filterHeight / 2);
auto global_column = id.get_id(1) + (filterWidth / 2);
//filter need a special case for edges, but here it just skip them
for (int i = 0; i < filterHeight; i++) {
for (int j = 0; j < filterWidth; j++) {
value += filterAcc[i][j] * imageAcc[(id.get_id(0) + i) * width + id.get_id(1) + j];
}
}
filteredImageAcc[global_row * width + global_column] = (uchar)(value);
});
});
q.wait();
}
cv::Mat filteredImageResult(height, width, CV_8UC1, filteredImageData.data());
cv::namedWindow("filtered Image", cv::WINDOW_NORMAL);
cv::imshow("filtered Image", filteredImageResult);
cv::namedWindow("original Image", cv::WINDOW_NORMAL);
cv::imshow("original Image", image);
cv::waitKey(0);
return 0;
}
```
the original image is attached
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Escalated to our engineering team for further investigation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you tell us how to build your code? Which libraries of opencv need to be linked?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I did more tests, and I could locate where the error come from, in gpu the device will directly convert the float to uchar, any negative value will become 0 and values over 255 will become 255. however the cpu don't do that directly for some reason and it typecast the float to int first then to uchar, and when typecasting int to uchar it will only take the first 8 bits and ignore all the others similar to as using "value%256", that what lead to wrong results, I could reproduce the same wrong results in gpu by typecasting the value(float) to int then to uchar.
the error isn't related to opencv, using uchar array with buffer and accessor to it will give same results.
not sure if the error considered from the compiler or from the code itself.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the details. Based on your description, I reproduced your issue with a small reproducer. And reported this issue to our internal team. Will let you know when there is any update.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page