2014-07-20 38 views
0

我有一些代碼在鼠標選擇的圖像上的兩點之間畫線,然後顯示直方圖。 但是,當我按代碼所需按q時,出現錯誤,說R6010 abort()已被調用,並說VC++運行時錯誤。opencv r6010 abort()在visual studio 2013中被稱爲錯誤

請告訴我如何找到這個錯誤。

#include <vector> 
#include "opencv2/highgui/highgui.hpp" 
#include <opencv\cv.h> 
#include <iostream> 
#include<conio.h> 

using namespace cv; 
using namespace std; 

struct Data_point 
{ 
    int x; 
    unsigned short int y; 
}; 

int PlotMeNow(unsigned short int *values, unsigned int nSamples) 
{ 
    std::vector<Data_point> graph(nSamples); 

    for (unsigned int i = 0; i < nSamples; i++) 
    { 
     graph[i].x = i; 
     graph[i].y = values[i]; 
    } 

    cv::Size imageSize(5000, 500); // your window size 
    cv::Mat image(imageSize, CV_8UC1); 

    if (image.empty()) //check whether the image is valid or not 
    { 
     std::cout << "Error : Image cannot be created..!!" << std::endl; 
     system("pause"); //wait for a key press 
     return 0; 
    } 
    else 
    { 
     std::cout << "Good job : Image created successfully..!!" << std::endl; 
    } 

    // tru to do some ofesseting so the graph do not hide on x or y axis 
    Data_point dataOffset; 

    dataOffset.x = 20; 
    // we have to mirror the y axis! 
    dataOffset.y = 5000; 

    for (unsigned int i = 0; i<nSamples; ++i) 
    { 
     graph[i].x = (graph[i].x + dataOffset.x) * 3; 
     graph[i].y = (graph[i].y + dataOffset.y)/200; 
    } 

    // draw the samples 
    for (unsigned int i = 0; i<nSamples - 1; ++i) 
    { 
     cv::Point2f p1; 
     p1.x = graph[i].x; 
     p1.y = graph[i].y; 
     cv::Point2f p2; 
     p2.x = graph[i + 1].x; 
     p2.y = graph[i + 1].y; 
     cv::line(image, p1, p2, 'r', 1, 4, 0); 
    } 

    cv::namedWindow("MyWindow1", CV_WINDOW_AUTOSIZE); //create a window with the name "MyWindow" 
    cv::imshow("MyWindow1", image); //display the image which is stored in the 'img' in the "MyWindow" window 
    while (true) 
    { 
     char c = cv::waitKey(10); 
     if (c == 'q') 
      break; 
    } 
    destroyWindow("MyWindow1"); 
    destroyWindow("MyWindow"); //destroy the window with the name, "MyWindow" 
    return 0; 
} 



void IterateLine(const Mat& image, vector<ushort>& linePixels, Point p2, Point p1, int* count1) 
{ 
    LineIterator it(image, p2, p1, 8); 

    for (int i = 0; i < it.count; i++, it++) 
    { 
     linePixels.push_back(image.at<ushort>(it.pos())); //doubt 
    } 

    *count1 = it.count; 
} 


//working line with mouse 
void onMouse(int evt, int x, int y, int flags, void* param) 
{ 
    if (evt == CV_EVENT_LBUTTONDOWN) 
    { 
     std::vector<cv::Point>* ptPtr = (std::vector<cv::Point>*)param; 
     ptPtr->push_back(cv::Point(x, y)); 
    } 
} 


void drawline(Mat image, std::vector<Point>& points) 
{ 
    cv::namedWindow("Output Window"); 
    cv::setMouseCallback("Output Window", onMouse, (void*)&points); 

    int X1 = 0, Y1 = 0, X2 = 0, Y2 = 0; 

    while (1) 
    { 
     cv::imshow("Output Window", image); 

     if (points.size() > 1) //we have 2 points 
     { 
      for (auto it = points.begin(); it != points.end(); ++it) 
      { 
      } 
      break; 
     } 
     waitKey(10); 
    } 


    //just for testing that we are getting pixel values 
    X1 = points[0].x; 
    X2 = points[1].x; 

    Y1 = points[0].y; 
    Y2 = points[1].y; 

    // Draw a line 
    line(image, Point(X1, Y1), Point(X2, Y2), 'r', 2, 8); 
    cv::imshow("Output Window", image); 

    //exit image window 
    while (true) 
    { 
     char c = cv::waitKey(10); 
     if (c == 'q') 
      break; 
    } 
    destroyWindow("Output Window"); 
} 


void show_histogram_image(Mat img1) 
{ 
    int sbins = 65536; 
    int histSize[] = { sbins }; 
    float sranges[] = { 0, 65536 }; 
    const float* ranges[] = { sranges }; 
    cv::MatND hist; 
    int channels[] = { 0 }; 
    cv::calcHist(&img1, 1, channels, cv::Mat(), // do not use mask 
      hist, 1, histSize, ranges, 
      true, // the histogram is uniform 
      false); 

    double maxVal = 0; 
    minMaxLoc(hist, 0, &maxVal, 0, 0); 
    int xscale = 10; 
    int yscale = 10; 

    cv::Mat hist_image; 
    hist_image = cv::Mat::zeros(65536, sbins*xscale, CV_16UC1); 

    for int s = 0; s < sbins; s++) 
    { 
     float binVal = hist.at<float>(s, 0); 
     int intensity = cvRound(binVal * 65535/maxVal); 

     rectangle(hist_image, cv::Point(s*xscale, hist_image.rows), 
      cv::Point((s + 1)*xscale - 1, hist_image.rows - intensity), 
      cv::Scalar::all(65535), 1); 

    } 


    imshow("Histogram", hist_image); 
    waitKey(0); 
} 


int main() 
{ 
    vector<Point> points1; 
    vector<ushort>linePixels; 

    Mat img = cvLoadImage("desert.jpg"); 

    if (img.empty()) //check whether the image is valid or not 
    { 
     cout << "Error : Image cannot be read..!!" << endl; 
     system("pause"); //wait for a key press 
     return -1; 
    } 
    //Draw the line 
    drawline(img, points1); 

    //now check the collected points 
    Mat img1 = cvLoadImage("desert.jpg"); 

    if (img1.empty()) //check whether the image is valid or not 
    { 
     cout << "Error : Image cannot be read..!!" << endl; 
     system("pause"); //wait for a key press 
     return -1; 
    } 

    int *t = new int; 
    IterateLine(img1, linePixels, points1[1], points1[0], t); 
    PlotMeNow(&linePixels[0], t[0]); 

    show_histogram_image(img); 
    delete t; 
    _getch(); 
    return 0; 
} 
+1

VS有一個很棒的調試 - 用它來逐步執行代碼。此外,格式化您的代碼,並消除所有多餘的東西,請在您的問題中明確 - 目前還不清楚問題出現在哪個waitKey之後。最後,爲什麼不''int t; IterateLine(...,&t);'? – Bull

+0

問題已解決您的評論幫助我thankyou –

+0

如果我的答案是有幫助的,你應該投票:-)。如果你描述瞭解決方案,它可能對他人有幫助。 – Bull

回答

1

這是你的代碼的臭味一個

void IterateLine(const Mat& image, vector<ushort>& linePixels, Point p2, Point p1, int* count1) 
{ 
    ... 
     linePixels.push_back(image.at<ushort>(it.pos())); //doubt 

現在image是CV_8UC3圖像(從Mat img1 = cvLoadImage("desert.jpg");,但喜歡它CV_16UC1,有什麼讓你在這裏訪問放入linePixels就是垃圾,這幾乎肯定會導致PlotMeNow()在圖片外面畫出來,並且破壞了一些東西,這可能就是爲什麼你的代碼崩潰的原因了。

正弦這是很不清楚你的代碼試圖做什麼,我不能建議你應該在這裏,而不是。

1

我剛纔已經成功地做到這一點,你只有把「-1」到你的循環限制:

for (unsigned int i = 0; i < nSamples-1; i++) 
{ 
    graph[i].x = i; 
    graph[i].y = values[i]; 
}