使用 opencv 分割失败(核心转储)
segmentation failed (core dumped) working with opencv
我 运行遇到了一个问题,试图在 Ubuntu 18.04LTS
上使用 OpenCV 执行模板匹配
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
int match_method =5;
string image_window = "Source Image";
string result_window = "Result window";
Mat img, templ, result;
/// Load image and template
img = imread("./RI2.jpg", IMREAD_GRAYSCALE );
templ = imread("./Pump2.jpg", IMREAD_GRAYSCALE );
/// Create windows
//namedWindow( image_window, WINDOW_AUTOSIZE );
//namedWindow( result_window, WINDOW_AUTOSIZE );
/// Source image to display
Mat img_display;
img.copyTo( img_display );
/// Create the result matrix
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
result.create( result_rows, result_cols, CV_32FC1 );
/// Do the Matching and Normalize
matchTemplate( img, templ, result, match_method );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
Mat resultgrey(result_rows, result_cols, CV_8UC1);
cout << "resultgrey.size().width: " << resultgrey.size().width << endl;
cout << "resultgrey.size().height: " << resultgrey.size().height << endl;
cout << "result.size().width: " << result.size().width << endl;
cout << "result.size().height: " << result.size().height << endl;
if( match_method == 0 || match_method == 1 )
{
for (int i=0; i<result.size().width; i++)
{
for (int j=0; j<result.size().height; j++)
{
if (result.at<float>(i,j)>=0.1)
{
resultgrey.at<int>(i,j)=0;
}
else
{
resultgrey.at<int>(i,j)=1;
}
}
}
}
else
{
for (int i=0; i<result.size().width; i++)
{
for (int j=0; j<result.size().height; j++)
{
if (result.at<float>(i,j)<=0.98)
{
resultgrey.at<int>(i,j)=0;
//cout << "0" << endl;
}
else
{
resultgrey.at<int>(i,j)=1;
//cout << "1" << endl;
}
}
}
}
cout << "3" << endl;
/// Localizing the objects
vector<Point> matchLoclist;
//cout << resultgrey << endl;
findNonZero(resultgrey, matchLoclist);
cout << "4" << endl;
if (matchLoclist.size() == 0)
{
cout << "no matches found" << endl;
return 0;
}
///Draw Rectangles on Pumps found in the scene
for (int i=0; i<matchLoclist.size(); i++)
{
//cout << "matchLoclist[i].x: "<<matchLoclist[i].x << endl << "matchLoclist[i].y: " << matchLoclist[i].y << endl;
rectangle( img_display, matchLoclist[i], Point( matchLoclist[i].x + templ.cols, matchLoclist[i].y + templ.rows ), Scalar::all(0), 2, 8, 0 );
rectangle( result, matchLoclist[i], Point( matchLoclist[i].x + templ.cols, matchLoclist[i].y + templ.rows ), Scalar::all(0), 2, 8, 0 );
}
imshow( image_window, img_display );
imshow( result_window, result );
waitKey(0);
return 0;
}
作为输出我得到:
xxx@ubuntu:~/Projects/Template_matching$ ./template_matching
resultgrey.size().宽度:1216
resultgrey.size().身高:723
result.size().宽度:1216
result.size().身高:723
分段错误(核心已转储)
这发生在双 for 循环期间,其中 1 或 0 被写入 "resultrgrey",因为我从来没有从下面的 cout
中得到“3”作为输出
如果我拍摄不同的输入图片(尤其是较小的图片),程序会 运行 而不会出现此错误。
感谢任何帮助或建议!
亚历克斯
由于 (1) 错误指定的数据类型和 (2) 将参数交换到 .at
,您在分配的缓冲区之外写入,正如 @rafix07 所指出的。
您创建了 8 位矩阵(CV_8UC1
中的 8):
Mat resultgrey(result_rows, result_cols, CV_8UC1);
但尝试将 32 位值分配给 double-for 循环中的元素:
resultgrey.at<int>(i,j)=0;
模板方法 cv::Mat::at
计算内存中第 (i,j)
个元素的地址,基于:
- 数据类型,在模板实例化中指定,
- 指向数据开始的指针,存储在
cv::Mat
实例中,
- 和数据跨度(两个连续行的最左边像素之间的字节距离),也存储在
cv::Mat
实例中。
然后returns引用它。为了速度,不执行任何检查,因此您有责任提交正确的参数。
int
的大小在大多数现代平台上是 32 位,但可以不同。
通常,使用来自 stdint.h
header 的类型更安全,这些类型具有明确的长度并在其名称中签名:uint8_t
、int32_t
等
查看有关 Mat::at
方法的参考资料
const _Tp& cv::Mat::at ( int i0, int i1 ) const
Parameters
i0 Index along the dimension 0
i1 Index along the dimension 1
第一个维度是行数,第二个维度是列数,因此您应该将代码中的所有行更改为 at
resultgrey.at<int>(i,j) // i means col, j means row
至
resultgrey.at<int>(j,i)
我 运行遇到了一个问题,试图在 Ubuntu 18.04LTS
上使用 OpenCV 执行模板匹配#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
int match_method =5;
string image_window = "Source Image";
string result_window = "Result window";
Mat img, templ, result;
/// Load image and template
img = imread("./RI2.jpg", IMREAD_GRAYSCALE );
templ = imread("./Pump2.jpg", IMREAD_GRAYSCALE );
/// Create windows
//namedWindow( image_window, WINDOW_AUTOSIZE );
//namedWindow( result_window, WINDOW_AUTOSIZE );
/// Source image to display
Mat img_display;
img.copyTo( img_display );
/// Create the result matrix
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
result.create( result_rows, result_cols, CV_32FC1 );
/// Do the Matching and Normalize
matchTemplate( img, templ, result, match_method );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
Mat resultgrey(result_rows, result_cols, CV_8UC1);
cout << "resultgrey.size().width: " << resultgrey.size().width << endl;
cout << "resultgrey.size().height: " << resultgrey.size().height << endl;
cout << "result.size().width: " << result.size().width << endl;
cout << "result.size().height: " << result.size().height << endl;
if( match_method == 0 || match_method == 1 )
{
for (int i=0; i<result.size().width; i++)
{
for (int j=0; j<result.size().height; j++)
{
if (result.at<float>(i,j)>=0.1)
{
resultgrey.at<int>(i,j)=0;
}
else
{
resultgrey.at<int>(i,j)=1;
}
}
}
}
else
{
for (int i=0; i<result.size().width; i++)
{
for (int j=0; j<result.size().height; j++)
{
if (result.at<float>(i,j)<=0.98)
{
resultgrey.at<int>(i,j)=0;
//cout << "0" << endl;
}
else
{
resultgrey.at<int>(i,j)=1;
//cout << "1" << endl;
}
}
}
}
cout << "3" << endl;
/// Localizing the objects
vector<Point> matchLoclist;
//cout << resultgrey << endl;
findNonZero(resultgrey, matchLoclist);
cout << "4" << endl;
if (matchLoclist.size() == 0)
{
cout << "no matches found" << endl;
return 0;
}
///Draw Rectangles on Pumps found in the scene
for (int i=0; i<matchLoclist.size(); i++)
{
//cout << "matchLoclist[i].x: "<<matchLoclist[i].x << endl << "matchLoclist[i].y: " << matchLoclist[i].y << endl;
rectangle( img_display, matchLoclist[i], Point( matchLoclist[i].x + templ.cols, matchLoclist[i].y + templ.rows ), Scalar::all(0), 2, 8, 0 );
rectangle( result, matchLoclist[i], Point( matchLoclist[i].x + templ.cols, matchLoclist[i].y + templ.rows ), Scalar::all(0), 2, 8, 0 );
}
imshow( image_window, img_display );
imshow( result_window, result );
waitKey(0);
return 0;
}
作为输出我得到:
xxx@ubuntu:~/Projects/Template_matching$ ./template_matching
resultgrey.size().宽度:1216
resultgrey.size().身高:723
result.size().宽度:1216
result.size().身高:723
分段错误(核心已转储)
这发生在双 for 循环期间,其中 1 或 0 被写入 "resultrgrey",因为我从来没有从下面的 cout
中得到“3”作为输出如果我拍摄不同的输入图片(尤其是较小的图片),程序会 运行 而不会出现此错误。
感谢任何帮助或建议!
亚历克斯
由于 (1) 错误指定的数据类型和 (2) 将参数交换到 .at
,您在分配的缓冲区之外写入,正如 @rafix07 所指出的。
您创建了 8 位矩阵(CV_8UC1
中的 8):
Mat resultgrey(result_rows, result_cols, CV_8UC1);
但尝试将 32 位值分配给 double-for 循环中的元素:
resultgrey.at<int>(i,j)=0;
模板方法 cv::Mat::at
计算内存中第 (i,j)
个元素的地址,基于:
- 数据类型,在模板实例化中指定,
- 指向数据开始的指针,存储在
cv::Mat
实例中, - 和数据跨度(两个连续行的最左边像素之间的字节距离),也存储在
cv::Mat
实例中。
然后returns引用它。为了速度,不执行任何检查,因此您有责任提交正确的参数。
int
的大小在大多数现代平台上是 32 位,但可以不同。
通常,使用来自 stdint.h
header 的类型更安全,这些类型具有明确的长度并在其名称中签名:uint8_t
、int32_t
等
查看有关 Mat::at
方法的参考资料
const _Tp& cv::Mat::at ( int i0, int i1 ) const Parameters i0 Index along the dimension 0 i1 Index along the dimension 1
第一个维度是行数,第二个维度是列数,因此您应该将代码中的所有行更改为 at
resultgrey.at<int>(i,j) // i means col, j means row
至
resultgrey.at<int>(j,i)