C++ Openmp c++;Sobel边缘检测
我对最终的图片有一个问题,它是扭曲的,我不知道为什么。只有在VisualStudio中打开openmp选项时才会出现这种情况。如果一条线可以使用,则没有问题,且边缘清晰。代码就在下面C++ Openmp c++;Sobel边缘检测,c++,openmp,edge-detection,C++,Openmp,Edge Detection,我对最终的图片有一个问题,它是扭曲的,我不知道为什么。只有在VisualStudio中打开openmp选项时才会出现这种情况。如果一条线可以使用,则没有问题,且边缘清晰。代码就在下面 #include "stdafx.h" #include<iostream> #include<omp.h> #include<cmath> #include<opencv2/imgproc/imgproc.hpp> #include<opencv2/highg
#include "stdafx.h"
#include<iostream>
#include<omp.h>
#include<cmath>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int xGradient(Mat image, int x, int y)
{
return image.at<uchar>(y-1, x-1) +
2*image.at<uchar>(y, x-1) +
image.at<uchar>(y+1, x-1) -
image.at<uchar>(y-1, x+1) -
2*image.at<uchar>(y, x+1) -
image.at<uchar>(y+1, x+1);
}
int yGradient(Mat image, int x, int y)
{
return image.at<uchar>(y-1, x-1) +
2*image.at<uchar>(y-1, x) +
image.at<uchar>(y-1, x+1) -
image.at<uchar>(y+1, x-1) -
2*image.at<uchar>(y+1, x) -
image.at<uchar>(y+1, x+1);
}
int main()
{
Mat src, grey, dst;
double start, end;
start = omp_get_wtime();
int gx, gy, sum;
src= imread("E:/image.jpg");
cvtColor(src,grey,CV_BGR2GRAY);
dst = grey.clone();
if( !grey.data )
{ return -1; }
#pragma omp parallel for
for(int y = 0; y < grey.rows; y++)
for(int x = 0; x < grey.cols; x++)
dst.at<uchar>(y,x) = 0;
#pragma omp parallel for
for(int y = 1; y < grey.rows - 1; y++){
for(int x = 1; x < grey.cols - 1; x++){
gx = xGradient(grey, x, y);
gy = yGradient(grey, x, y);
sum = abs(gx) + abs(gy);
sum = sum > 255 ? 255:sum;
sum = sum < 0 ? 0 : sum;
dst.at<uchar>(y,x) = sum;
}
}
namedWindow("sobel");
imshow("sobel", dst);
namedWindow("grayscale");
imshow("grayscale", grey);
namedWindow("Original");
imshow("Original", src);
end = omp_get_wtime();
cout<<"time is: "<<(end-start)<< " seconds" <<endl;
waitKey();
return 0;
}
#包括“stdafx.h”
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
使用名称空间cv;
int x梯度(Mat图像,int x,int y)
{
返回图像。在(y-1,x-1)+
2*at(y,x-1)处的图像+
图像。在(y+1,x-1)处-
图像。在(y-1,x+1)-
2*at(y,x+1)处的图像-
图像.at(y+1,x+1);
}
int YGRADENT(Mat图像,int x,int y)
{
返回图像。在(y-1,x-1)+
2*at(y-1,x)处的图像+
图像。在(y-1,x+1)-
图像。在(y+1,x-1)处-
在(y+1,x)处的2*图像-
图像.at(y+1,x+1);
}
int main()
{
材料src,灰色,dst;
双起点,双终点;
start=omp_get_wtime();
整数gx,gy,和;
src=imread(“E:/image.jpg”);
CVT颜色(src、灰色、CV_BGr2灰色);
dst=grey.clone();
如果(!grey.data)
{return-1;}
#pragma-omp并行
对于(int y=0;y255?255:总和;
总和=总和<0?0:总和;
(y,x)处的dst=总和;
}
}
namedWindow(“sobel”);
imshow(“sobel”,dst);
名称(“灰度”);
imshow(“灰度”,灰色);
姓名(以下简称“原件”);
imshow(“原件”,src);
end=omp_get_wtime();
cout在gx
、gy
和sum
中存在竞态条件。它们都是共享的,应该是私有的。在并行循环中使用它们时,只需定义它们,就可以解决您的问题。就像这样
#pragma omp parallel for
for(int y = 1; y < grey.rows - 1; y++){
for(int x = 1; x < grey.cols - 1; x++){
int gx = xGradient(grey, x, y);
int gy = yGradient(grey, x, y);
int sum = abs(gx) + abs(gy);
sum = sum > 255 ? 255:sum;
sum = sum < 0 ? 0 : sum;
dst.at<uchar>(y,x) = sum;
#pragma omp parallel for
对于(int y=1;y255?255:总和;
总和=总和<0?0:总和;
(y,x)处的dst=总和;
我希望这能帮助你:)
#pragma omp parallel for private(gx,gy,sum)//num_线程(2)
对于(int y=1;y255?255:总和;
总和=总和<0?0:总和;
(y,x)处的dst=总和;
}
}
#用于折叠的pragma omp并行(2)?只是一个猜测,你希望两者并行,如果不是的话,我错了~~~你已经编写了一个数据竞赛。当然,这是一个猜测,但为了排除这种可能性,你应该明确声明每个并行区域中所有变量的可访问性:private
,shared
,what-have-you。在gx
中有一个竞赛条件gy
和sum
。它们都是共享的,应该是私有的。在并行循环中使用它们时只需定义它们,就可以解决您的问题。工作正常,最终图像现在已清晰。但我有另一个问题:openmp的时间比单线程的时间长。对于图像8000x5330,操作持续37859秒使用openmp(4个线程)的openmp和5746是什么?知道如何提高速度吗?我不知道。看起来还可以。可能存在一些错误共享,但我现在看不到。您只在行上进行了并行循环,因此任何线程都不应该写入同一行。什么是'dst.at(y,x)`?它与dst[width*y+x]相同吗?如果文本格式更好,您可能会得到更多的响应。突出显示文本并键入ctrl-k,然后修复任何仍然不正确的问题。
#pragma omp parallel for private (gx, gy, sum) //num_threads (2)
for(int y = 1; y < grey.rows - 1; y++){
for(int x = 1; x < grey.cols - 1; x++){
gx = xGradient(grey, x, y);
gy = yGradient(grey, x, y);
sum = abs(gx) + abs(gy);
sum = sum > 255 ? 255:sum;
sum = sum < 0 ? 0 : sum;
dst.at<uchar>(y,x) = sum;
}
}