Mat scaling affects only first channel (Bug #3227)
Description
When a matrix constructed with Mat::ones() is scaled with * operator, it affects only the first channel.
The code to reproduce is below, the displayed image is all blue.
1Mat3b img = Mat3b::ones(600,600)*255;
2imshow("img", img);
3waitKey();
Associated revisions
Merge pull request #3227 from PhilLab:patch-3
History
Updated by Baris Demiroz over 11 years ago
If this is the intended behavior it should be in the documentation. I couldn't find it in the docs, of course there is a chance I overlooked it.
Updated by be rak over 11 years ago
problem already starts here:
Mat3b img = Mat3b::ones(3,3);
cerr << img << endl;
[ 1, 0, 0, 1, 0, 0, 1, 0, 0;
1, 0, 0, 1, 0, 0, 1, 0, 0;
1, 0, 0, 1, 0, 0, 1, 0, 0]
or, for a change:
Mat img = Mat::eye(3,3,CV_8UC3);
cerr << img << endl;
[ 1, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 1, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 1, 0, 0]
#---------------------------------------------------------------------------------------
tracked it down to core\src\matop.cpp, L1555 :
void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int _type) const
{
if( _type == -1 )
_type = e.a.type();
if( e.a.dims <= 2 )
m.create(e.a.size(), _type);
else
m.create(e.a.dims, e.a.size, _type);
if( e.flags == 'I' && e.a.dims <= 2 )
setIdentity(m, Scalar(e.alpha));
else if( e.flags == '0' )
m = Scalar();
else if( e.flags == '1' )
m = Scalar(e.alpha);
else
CV_Error(CV_StsError, "Invalid matrix initializer type");
}
as you can see, in both 'I' and '1' cases, Scalar(e.alpha) is used(which only initializes the 1st element).
it's a bit unclear to me, what the desired behaviour is here. should Mat::ones() and Mat::eye() only be used with 1 channel Mat's ? then that needs clarification.
using Scalar::all(e.alpha) instead would fix it otherwise:
#---------------------------------------------------------------------------------------
Mat3b img = Mat3b::ones(3,3);
cerr << img << endl;
[ 1, 1, 1, 1, 1, 1, 1, 1, 1;
1, 1, 1, 1, 1, 1, 1, 1, 1;
1, 1, 1, 1, 1, 1, 1, 1, 1]
Mat img = Mat::eye(3,3,CV_8UC3);
cerr << img << endl;
[1, 1, 1, 0, 0, 0, 0, 0, 0;
0, 0, 0, 1, 1, 1, 0, 0, 0;
0, 0, 0, 0, 0, 0, 1, 1, 1]
Updated by Dinar Ahmatnurov over 11 years ago
- Status changed from New to Open
Updated by Dinar Ahmatnurov over 11 years ago
"using Scalar::all(e.alpha) instead would fix it otherwise" as for me it sounds good, could you please open PR on github with your changes? Kirill, any additions?
- Assignee changed from Vadim Pisarevsky to Kirill Kornyakov
Updated by be rak over 11 years ago
Updated by Dinar Ahmatnurov over 11 years ago
perfect, 10x!
Updated by Kirill Kornyakov over 11 years ago
- Target version set to 2.4.7
- HW Platform changed from x64 to Any
- Operating System changed from Windows to Any
- Pull request set to https://github.com/Itseez/opencv/pull/1331
- Difficulty set to Easy
Updated by Kirill Kornyakov over 11 years ago
@Berak, was it finally merged to the repo? I can see the branch b_3227_24 in your repo, but I'm not sure if it was merged...
Updated by Alexander Smorkalov over 11 years ago
@Berak, was the problem solved? Was the solution merged to OpenCV repository?
- Pull request deleted (
https://github.com/Itseez/opencv/pull/1331) - Affected version changed from 2.4.6 (latest release) to 2.4.0 - 2.4.6
Updated by Alexander Smorkalov over 11 years ago
@Berak, was the problem solved? Was the solution merged to OpenCV repository?
Updated by Alexander Smorkalov over 11 years ago
- Target version changed from 2.4.7 to 2.4.8
Updated by be rak over 11 years ago
sorry, it took so long, finally found out, how to do a proper 2.4 pr
i assumed, setIdentity() should behave the same way now, right ?
Updated by Ilya Lavrenov about 11 years ago
as you can see from https://github.com/Itseez/opencv/pull/1900 this behaviour of Mat::ones() is expected, closed.
- Status changed from Open to Cancelled