C++ Openmp c++;Sobel边缘检测

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

我对最终的图片有一个问题,它是扭曲的,我不知道为什么。只有在VisualStudio中打开openmp选项时才会出现这种情况。如果一条线可以使用,则没有问题,且边缘清晰。代码就在下面

#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;
        }
    }