我对此代码有疑问:
问题是,当我看到图像原始时,被“borrarFondo()”修改但是这个函数是从“segmentarHoja”调用的,这里输入img的值,但是img修改了。
void borrarFondo(Mat& img){
img = ~img;
Mat background;
medianBlur(img, background, 45);
GaussianBlur(background, background, Size(203,203),101,101);
img = img - background;
img = ~img;
}
void segmentarHoja(Mat img, Mat& imsheet){
Mat imgbw;
borrarFondo(img); //borrarFondo is called from here where img is a copy
cvtColor(img, imgbw, CV_BGR2GRAY);
threshold(imgbw, imgbw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
Mat element = getStructuringElement(MORPH_ELLIPSE, Size(21,21));
erode(imgbw, imgbw, element);
vector<vector<Point> > contoursSheet;
findContours(imgbw, contoursSheet, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
vector<Rect> boundSheet(contoursSheet.size());
int largest_area=0;
for( int i = 0; i< contoursSheet.size(); i++ )
{
double a= contourArea( contoursSheet[i],false);
if(a>largest_area){
largest_area=a;
boundSheet[i] = boundingRect(contoursSheet[i]);
imsheet=img(boundSheet[i]).clone();
}
}
borrarFondo(imsheet);
}
int main()
{
Mat imsheet;
image= imread("c:/imagen.jpg");
segmentarHoja(image, imsheet);
imshow("imsheet",imsheet);
imshow("imagen",image); //original image by amending borrarFondo
waitKey(0);
}
我不想改变原始图像
答案 0 :(得分:2)
opencv Mat
是计数引用(例如std::shared_ptr
,除了不同的语法),其中复制构造或赋值不会复制。使用clone
方法进行复制。阅读the documentation,总是一个好主意。
答案 1 :(得分:1)
如果您正在做这样的事情:
Mat a;
Mat b = a;
或者像这样:
void func(Mat m) {...}
或:
vector<Mat> vm;
vm.push_back(m);
所有这些都是浅副本。 Mat标题将是一个副本,指针也在里面。
所以,例如在第一个示例中,b和a共享相同的大小和数据成员
这可能解释了为什么按值传递Mat仍会导致从“浅”副本操纵像素。
要避免您必须执行“深度”复制:
Mat c = a.clone(); // c has its own pixels now.
同样,如果你不想操纵你的Mat,那么将它作为传递给你如何使用它,如下图所示。const Mat &
#include <opencv2/opencv.hpp>
void foo( cv::Mat const& image )
{
cv::Mat result = image;
cv::ellipse(
result, // img
cv::Point( 300, 300 ), // center
cv::Size( 50, 50 ), // axes (bounding box size)
0.0, // angle
0.0, // startAngle
360.0, // endAngle
cv::Scalar_<int>( 0, 0, 255 ), // color
6 // thickness
);
}
auto main() -> int
{
auto window_name = "Display";
cv::Mat lenna = cv::imread( "lenna.png" );
foo( lenna );
imshow( window_name, lenna );
cv::waitKey( 0 );
}
Mat const&
谎称可变性,而Lenna的鼻子相应长,这里标有上面foo
函数放置的大胖圈: