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

조회 수: 3 (최근 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