【问题标题】:Segmentation error when trying to equalize an image尝试均衡图像时出现分割错误
【发布时间】:2017-11-19 21:32:15
【问题描述】:

我一直在阅读有关opencv的信息并且一直在做一些练习,在这种情况下我想执行图像均衡,我已经实现了以下代码,但是当我执行它时,我得到了以下错误:

“分段错误(核心转储)”

所以我不知道什么时候到期。

我尝试使用的公式如下:

equalization

代码如下:

 #include <opencv2/opencv.hpp>
 #include <opencv2/highgui/highgui.hpp> 
 #include <stdio.h>

 using namespace cv;
 using namespace std;

 void equalization(cv::Mat &image,cv::Mat &green, int m) {
 Mat eqIm;
 int nl= image.rows; // number of lines

int nc= image.cols * image.channels();
for (int j=0; j<nl; j++) {

    uchar* data= image.ptr<uchar>(j);
    uchar* data2= green.ptr<uchar>(j);
    uchar* eqIm= green.ptr<uchar>(j);

    for (int i=0; i<nc; i++) {

        eqIm[i]= data[i]+m-data2[i];

    }
 }
 cv::imshow("Image",eqIm);
 imwrite("eqIm.png",eqIm);
 }

float mean(cv::Mat &image){
   cv:Scalar tempVal = mean( image );
   float myMAtMean = tempVal.val[0];
   cout << "The value is " << myMAtMean;
 }

 int main(int argc, char** argv ){
 Mat dst;
 Mat image= cv::imread("img.jpg");
 Mat green= cv::imread("green.jpg");

 cv::imshow("Image",image);
 float m= mean(image);

 equalization(image,green,m);
 cv::namedWindow("Image");
 cv::imshow("Image",image);
 imwrite("equalizated.png",dst);
 waitKey(0);
 return 0;

}

并且写入的图像“Equalization.png”什么都不包含

【问题讨论】:

  • 除了胡椒杰克的回答:Avoid using namespace |不要包含你不需要的东西(为什么stdio.h?)|编译时,启用警告并将其视为错误。 |人们会期望一个名为 mean 的函数计算并返回平均值,而不是将其打印到控制台并通过省略 return 语句导致 UB。 |同样,人们会期望equalization 实际返回均衡后的图像,而不是将其保存到硬编码文件、弹出窗口、丢弃结果并期待......
  • ... 用户(如在程序员中使用该函数)记得在之后调用waitKey 以使可视化工作。 (POLA) |最后,熟悉 OpenCV 文档,尤其是基本类型,例如 cv::Mat 以及它们上可用的操作。然后使用那些高级抽象。比如equalization的body基本就是Mat eqIm = image + m - green;

标签: c++ image opencv equalizer


【解决方案1】:

你从来没有初始化Mat eqIm,所以当你做cv::imshow("Image", eqIm); imwrite("eqIm.png", eqIm);时,垫子里什么都没有。 https://docs.opencv.org/2.4/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html

另外,我应该注意你有两个变量eqIm。这可能是混乱的一部分。

最后一件事,在你的mean 函数中,你可能会得到一个递归函数。您应该在创建的平均函数中指定您使用的平均函数,即

float mean(cv::Mat &image) {
cv:Scalar tempVal = cv::mean(image);
    float myMAtMean = tempVal.val[0];
    cout << "The value is " << myMAtMean;
    return myMAtMean;
}

以下内容更接近于您在均衡函数中寻找的内容。

void equalization(cv::Mat &image, cv::Mat &green, int m) {
    Mat eqIm(image.rows,image.cols,image.type());
    int nl = image.rows; // number of lines
    int nc = image.cols * image.channels();
    for (int j = 0; j<nl; j++) {// j is each row
        for (int ec = 0; ec < nc; ec++) {//ec is each col and channels
                eqIm.data[j*image.cols*image.channels() + ec] = image.data[j*image.cols*image.channels() + ec] + m - green.data[j*image.cols*image.channels() + ec];
        }
    }
    cv::imshow("Image", eqIm);
    imwrite("eqIm.png", eqIm);
}

我通过j*image.cols*image.channels() 逐步检查整个 j 行的大小(列数乘以每个像素的通道数)。

【讨论】:

  • 我运行此代码,但出现此错误:OpenCV 错误:imshow 中的断言失败 (size.width>0 && size.height>0),文件 /opt/opencv/modules/highgui/src /window.cpp,第 331 行终止在抛出“cv::Exception”实例后调用什么():/opt/opencv/modules/highgui/src/window.cpp:331:错误:(-215)size.width >0 && size.height>0 in function imshow Aborted (core dumped) 我不明白你在这一步做了什么 eqIm.data[jimage.colsimage.channels() + ec] = image.data[jimage.colsimage.channels() + ec] + m - green.data[jimage.colsimage.channels() + ec];为什么选择 eqIm.data?
  • @Colours123 尝试用int main(int argc, char** argv) { Mat image = cv::imread("img.jpg"); Mat green = cv::imread("green.jpg"); cv::imshow("Image", image); float m = mean(image); equalization(image, green, m); cv::namedWindow("Image"); cv::imshow("Image", image); waitKey(0); return 0; } 替换主循环。旧代码中有一个名为 dst 的 Mat,它在保存时可能会导致问题,因为它也没有被分配。 还有一件事... 与您的原始代码一样,两个输入图像必须具有相同的格式和大小。
  • @Colours123 eqIm.data 为我们提供了一个指向图像交错通道数据的指针(此处的顶行示例:i.stack.imgur.com/LNJPs.png)。然后我只为 eqIm、green 和 image 中的每个通道运行均衡方程。
  • 呃……当我回读我发送的内容时,我意识到我说过“主循环”这当然是完全错误的,但编辑我的评论为时已晚。澄清一下,它只运行一次。 (在此之前,我一直在编写一些嵌入式代码,其中 main 函数是一个循环)
猜你喜欢
  • 2017-02-07
  • 1970-01-01
  • 1970-01-01
  • 2021-09-08
  • 2017-04-25
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
相关资源
最近更新 更多