0

I am working on a project. I have here a vector<Mat> cache. Somehow I am getting a weird error (I have already checked other solutions but its still occurring) when I run this module:

if(cache.size() == 10)
{
  Mat sum_template = Mat::zeros(cache.at(1).size(), cache.at(1).type());

  for(int i=0; i<cache.size(); i++)
  {
    sum_template += cache.at(i);
    imshow("sum_template", sum_template);   waitKey();
  }
}

What I want to do is, add each of Mat inside cache to sum_template. But, following error comes up on the line sum_template += cache.at(i);:

The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function arithm_op

I am simply adding Mats. I checked, the cache.at(i) is properly displayed before crashing and also the cache size is 10 it shows. Any idea what is wrong here??

EDIT the cache is a vector of matrices similar to result matrix R as shown here

learner
  • 1,197
  • 6
  • 22
  • 34
  • what happens if you write it like `sum_template = sum_template + cache.at(i)`? – Massa Apr 05 '14 at 00:34
  • Is Mat properly copyable? It needs to be if it is to be candidate within a std::vector and not show issues when you do various std::vector operations. – PaulMcKenzie Apr 05 '14 at 00:35
  • @Massa Same error. Its just a shorthand I tried for what you suggested... – learner Apr 05 '14 at 00:35
  • @PaulMcKenzie copyable? how? – learner Apr 05 '14 at 00:35
  • It should have `Mat::operator=(Mat&)` defined to be copyable... – Massa Apr 05 '14 at 00:37
  • @PaulMcKenzie I don't understand that. Could you please explain a little? OR, may be reflect it in my code? – learner Apr 05 '14 at 00:38
  • 1
    See this answer here: http://stackoverflow.com/questions/22841696/c-cannot-return-object-from-function/22842678#22842678 It talks about a different class (PolyTree), but the boilerplate code in the solution determines if the type can be safely used by a vector. A vector will be making copies, and if your type has a copy constructor that doesn't work correctly, then there is your problem. – PaulMcKenzie Apr 05 '14 at 00:39
  • @PaulMcKenzie please also check edit – learner Apr 05 '14 at 00:41
  • 1
    @learner - Yes, I see your link, but it doesn't matter what the class does on a high level. What we want to know is whether your class can make object copies safely. It doesn't matter what the underlying application is. Please see the link in my earlier comment -- does that tiny main() program pass the test of being copyable? Replace PolyTree with Mat, or whatever your class happens to be. Believe me, it is a reliable test, even though it's small. – PaulMcKenzie Apr 05 '14 at 00:44
  • 1
    Well, can you fill Mat with values? If so, then fill one with values, and run that test I linked to. That's all. Replace PolyTree with Mat, fill it with values, and perform the copies exactly like the last 3 lines in that program. If your program doesn't bomb out and no corruption occurs, then we pass that test. The ultimate test though is to go through your class and look for pointers and see how they're used. In the end, it may wind up that Mat is safely copyable, but we need to eliminate the cause of your problem being a "bad type placed in a vector". – PaulMcKenzie Apr 05 '14 at 00:47
  • @PaulMcKenzie I filled P1 with some imread(). And its copied well into others. They are displayed properly. What now? – learner Apr 05 '14 at 00:50
  • @learner - So you ran my program? If not, please do so. It tests destruction also, and it tests it by calling the destructor for 3 objects that have been copied and assigned. – PaulMcKenzie Apr 05 '14 at 00:53
  • @PaulMcKenzie I tested it. I put an image inside P1 using imread() function. And all of them showed the same image. – learner Apr 05 '14 at 00:54
  • You don't quite understand. I don't care what your program does. I want to know if std::vector will work properly with your type. We only know this if there are no side effects from copying, assignment, and *destruction*, and that is what that program I linked to does. – PaulMcKenzie Apr 05 '14 at 00:55
  • @PaulMcKenzie see, i filled the P1 as you suggested. And its getting copied well as I can check with imshow(). I am not able to understand what you are implying. I did test the code you sent. – learner Apr 05 '14 at 00:56
  • ok. That is all I want to know. The reason why I needed to know is that in the running of a program, everything may seem well, but when that pesky thing called a *destructor* starts to get invoked on copied objects, things then start to fall to pieces. – PaulMcKenzie Apr 05 '14 at 00:57
  • @PaulMcKenzie okey...frankly, i am still trying to understand what you told. But, what now? is there any solution? why is it happening so? – learner Apr 05 '14 at 00:59
  • 1
    What I'm saying is that std::vector is copying and destroying your objects in various operations that vector does. That is what that program tested, copying *and* destruction in a simple program. You only were observing whether the images were ok -- but that is not a valid test to thoroughly know whether that object can be copied and destroyed safely. – PaulMcKenzie Apr 05 '14 at 01:05
  • @PaulMcKenzie i just checked: both cache.at(i).type() and sum_template.type() give same type **5** but cache.at(i).size() is **[100 x 100]** whereas sum_template.size() is **[101 x 101]**. is that helpful? only cache.at(0).size() is **[100x100]** for all other i's it is **[101x101]** and also for sub_templates it is **[101x101]** – learner Apr 05 '14 at 01:19
  • @PaulMcKenzie YES!!! I GOT IT!!! THAT SIZE WAS THE PROBLEM!!! Don't know why but the very first image in cache is of size 100x100 whereas rest all are of 101x101. I resized first to 101x101 and its working!!! YUUHHOOOO!!! **THANK YOU VERY MUCH FOR YOUR TIME AND INPUTS.** **BUT, I WONDER WHY THAT SIZE THING HAPPENED!!!** – learner Apr 05 '14 at 01:29
  • @learner - Since I don't know how you populated the cache vector, can't tell you the reason. You should start out again with an empty vector, set cache(0), and observe how cache(1), cache(2), etc. are populated. If they are populated using direct copying that invokes the user-defined copy operator (or compiler generated one if a user-defined one doesn't exist), then the copy operator is faulty or must be (re)written to handle copying safely. – PaulMcKenzie Apr 05 '14 at 04:45
  • cache.size() (i – Vlad Apr 05 '14 at 04:57

0 Answers0