Perform mldivide between 3x3 matrix M and every RGB pixel in a image in GPU

2 次查看(过去 30 天)
I have a rgb image (2048x2048x3), and I wan to perform mldivide on every rgb (3,1) pixels with a M matrix (3x3).
So each pixel will do a M\pixel operation. The easy way to do this is using two for loops to go over each pixels. However, I am wondering if I can use arrayfun or pagefun for this so I can use GPU.
Right now in order to use arrayfun, I have to hard code mldivide so M becomes 9x4194304(2048*2048) array which takes lots of vram. I am wondering if there is a way I can run this without having a big M gpu array as input.
  3 个评论
Chi Huang
Chi Huang 2022-7-8
Sorry I made a mistake, it it will be a 3x1 matrix, rand(3,1). I forgot matlab has y,x convention.
Stephen23
Stephen23 2022-7-8
"Sorry I made a mistake, it it will be a 3x1 matrix, rand(3,1). I forgot matlab has y,x convention."
... I guess you mean all of mathematics has that convention: https://en.wikipedia.org/wiki/Matrix_(mathematics)

请先登录,再进行评论。

采纳的回答

Stephen23
Stephen23 2022-7-8
format compact
S = 5;
M = rand(3,3);
I = rand(S,S,3);
% reference:
A = nan(S,S,3);
for ii = 1:S
for jj = 1:S
pixel = reshape(I(ii,jj,:),3,1);
A(ii,jj,:) = M\pixel;
end
end
A
A =
A(:,:,1) = 4.2226 15.3976 9.7294 0.6686 -8.5764 15.5251 -0.8818 3.5689 4.1730 2.4676 7.1266 -6.9632 9.8103 10.5705 15.3470 7.5849 0.9940 16.1186 -0.2064 16.8039 -7.8875 -7.1051 0.2250 2.7415 -7.6742 A(:,:,2) = 0.7674 3.0061 1.4504 1.4626 0.3589 2.4699 2.0878 2.4253 1.5477 2.3345 1.0364 0.5316 1.4698 2.3068 2.5930 1.5519 2.5403 3.6515 1.6914 2.3027 0.6423 0.3699 1.7695 2.2491 0.0037 A(:,:,3) = -1.0156 -6.3149 -3.2293 -0.7714 2.6126 -5.7948 -0.6883 -2.1061 -2.1869 -1.4797 -2.2634 1.9633 -3.2872 -4.0813 -5.4468 -2.4617 -1.5182 -6.7929 -0.7229 -5.7964 2.5722 2.1096 -1.0220 -1.5365 2.8622
Remember that RESHAPE is a very fast operation (it does not change your data in memory, only the shape meta-data in its header). In contrast you want to avoid operations that rearrange your data in memory (e.g. TRANSPOSE, PEMUTE). Note that using PAGEFUN would require permutimh your data.
% RESHAPE() and TRANSPOSE() and MLDIVIDE():
B = reshape((M\reshape(I,S*S,3).').',S,S,3)
B =
B(:,:,1) = 4.2226 15.3976 9.7294 0.6686 -8.5764 15.5251 -0.8818 3.5689 4.1730 2.4676 7.1266 -6.9632 9.8103 10.5705 15.3470 7.5849 0.9940 16.1186 -0.2064 16.8039 -7.8875 -7.1051 0.2250 2.7415 -7.6742 B(:,:,2) = 0.7674 3.0061 1.4504 1.4626 0.3589 2.4699 2.0878 2.4253 1.5477 2.3345 1.0364 0.5316 1.4698 2.3068 2.5930 1.5519 2.5403 3.6515 1.6914 2.3027 0.6423 0.3699 1.7695 2.2491 0.0037 B(:,:,3) = -1.0156 -6.3149 -3.2293 -0.7714 2.6126 -5.7948 -0.6883 -2.1061 -2.1869 -1.4797 -2.2634 1.9633 -3.2872 -4.0813 -5.4468 -2.4617 -1.5182 -6.7929 -0.7229 -5.7964 2.5722 2.1096 -1.0220 -1.5365 2.8622
% we can simplify the above into RESHAPE() and MRDIVIDE():
C = reshape((reshape(I,S*S,3)/M.'),S,S,3) % recommended
C =
C(:,:,1) = 4.2226 15.3976 9.7294 0.6686 -8.5764 15.5251 -0.8818 3.5689 4.1730 2.4676 7.1266 -6.9632 9.8103 10.5705 15.3470 7.5849 0.9940 16.1186 -0.2064 16.8039 -7.8875 -7.1051 0.2250 2.7415 -7.6742 C(:,:,2) = 0.7674 3.0061 1.4504 1.4626 0.3589 2.4699 2.0878 2.4253 1.5477 2.3345 1.0364 0.5316 1.4698 2.3068 2.5930 1.5519 2.5403 3.6515 1.6914 2.3027 0.6423 0.3699 1.7695 2.2491 0.0037 C(:,:,3) = -1.0156 -6.3149 -3.2293 -0.7714 2.6126 -5.7948 -0.6883 -2.1061 -2.1869 -1.4797 -2.2634 1.9633 -3.2872 -4.0813 -5.4468 -2.4617 -1.5182 -6.7929 -0.7229 -5.7964 2.5722 2.1096 -1.0220 -1.5365 2.8622

更多回答(2 个)

Joss Knight
Joss Knight 2022-7-9
编辑:Joss Knight 2022-7-10
I feel like I'm missing something - this is just a single backslash with multiple right-hand sides, or to avoid permutation a single mrdivide (edit: you still have to transpose M, but that's very quick):
[h,w] = size(im,[1 2]);
imout = reshape(reshape(im,[],3)/(M.'), h, w, 3);
  23 个评论
Bruno Luong
Bruno Luong 2022-7-12
For b that is vector,
  • A\b complexity O(n^2),
  • inv(A)*b has O(n^3),
and you find various tic/toc along the discussion above.
For b that is n x m
  • A\b complexity O(n^2)+O(n*m),
  • inv(A)*b has O(n^3)+O(n*m),
with the O(n*m) much favarable to the inv(), possibly 6-10 time faster for small n and large m as for the OP's question here.
Paul
Paul 2022-7-12
No worries. I just deleted my comment that flagged your edit and it looks like Stephen23 deleted his related comment. If you delete your comment and can delete this comment as well, we'll go back to having a nice, clean thread as if it never happened.

请先登录,再进行评论。


Bruno Luong
Bruno Luong 2022-7-11
编辑:Bruno Luong 2022-7-11
B = reshape(reshape(I,[],3)*inv(M.'),size(I));

类别

Help CenterFile Exchange 中查找有关 Operating on Diagonal Matrices 的更多信息

产品


版本

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by