2014-01-06 302 views
1

我有一个最终图片的问题,它是扭曲的,我不知道为什么。只有当我在Visual Studio中打开openmp选项。如果它在一根线上工作,没有问题,边缘清晰。代码如下。Openmp C++ sobel边缘检测

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

感谢您的帮助和答案

+0

的#pragma OMP并行的崩溃(2)?只是一个你想要并行的猜测,如果不是,我错了~~~ – barfatchen

+0

你已经编写了数据竞赛。当然,这只是一个猜测,但要排除您应该明确声明每个并行区域中所有变量的可访问性的可能性:“private”,“shared”,what-have-you。 –

+0

'gx','gy'和'sum'有竞争条件。他们都是共享的,应该是私有的。只需在并行循环中使用它们时定义它们,它就可以解决您的问题。 –

回答

0

有一个在gxgysum的竞争条件。他们都是共享的,应该是私有的。只需在并行循环中使用它们时定义它们,它就可以解决您的问题。像这样

#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; 
+0

工作正常,现在最终图像清晰。但我还有一个问题:openmp的时间比单线程的时间要长。对于映像8000x5330,在没有openmp的情况下持续运行3,7859秒,在openmp(4个线程)下运行5,746秒。任何想法如何提高速度? – user3167262

+0

我不知道。它看起来没问题。也许有一些虚假的分享,但我现在看不到它。你只在行上做了循环并行,所以没有线程应该写入同一行。什么是'dst.at (y,x)'?它是否与dst [width * y + x]相同?如果您更好地设置文字的格式,则可能会得到更多回复突出显示文本并键入ctrl-k,然后修复任何不正确的东西。 –

0

我希望这可以帮助ü:)

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