0

I have ported most of the 24 methods from the SVG composition standard (2009, https://www.w3.org/TR/2009/WD-SVGCompositing-20090430/) in Matlab but four methods (like color-dodge) relay on comparing images within an if-statement (like: if Sca == Sa && Dca == 0 ...) but Matlab views this as nonscalar operators.

Sc, Dc are RGB images Sa, Da are gray masks that represents alpha channels Dca, Sca are pre-multiplied images: Dca = Dc .* Da; Sca = Sc .* Sa;

if strcmp(compo_meth, 'color-dodge') == 1; 
    if Sca == Sa && Dca == 0
        Dca = (1 - Da) .* Sca;
    elseif Sca == Sa
        Dca = Sa .* Da + (1 - Da) .* Sca + (1 - Sa) .* Dca;
    elseif Sca < Sa
        Dca = Sa .* Da .* min(1, Dca/Da .* Sa/(Sa - Sca));
    end
    Da  = Sa + Da - Sa .* Da;
end

error in if Sca == Sa && Dca == 0

Operands to the || and && operators must be convertible to logical scalar values

  • What results do you expect? What do you want these comparisons to do? – beaker Jun 04 '19 at 15:21
  • @beaker: please refer to the url above to retrace what such a non trivial method is doing. Here I am asking a technical Matlab question to compare images perhaps with a function img_compare(Sca, Sa, 'method', '=' or ' – Günter Bachelier Jun 04 '19 at 16:15
  • Sure, use `isequal()`. It won't do what you want, but it'll give you a logical scalar answer that will work in the if-statement. If you would like to describe what results you are looking for, I'll try to give you a more pertinent answer. Questions on Stack Overflow should be self-contained and not require outside resources in order to understand what is being asked, and should describe the desired behavior (see [help/on-topic]). – beaker Jun 04 '19 at 16:30
  • I interpret that "if Sca == Sa && Dca == 0" is a "macroscopic" formulation of comparing images: RGB Sca with mask Sa and RGB Dca with a black (zero array). On a pixel level this means that if the same pixel coordinate in Sca and Sa is equal and the corresponding pixel coordinate in Dca is 0 then the result pixel in Dca is computed as a weighted value of Sca with Da. Something like "if isequal(Sca(i,j,k), Sa(i,j,1)) == 1 & isequal(Dca(i,j,k), 0) == 1; Dca(i,j,k) = (1-Da(i,j,1))*Sca(i,j,k); end" – Günter Bachelier Jun 05 '19 at 07:32
  • This information needs to be in the question itself. I believe the only error in your condition statement is that you used the short-circuit logical operator `&&` instead of the elementwise operator `&`. – beaker Jun 05 '19 at 15:09
  • I tried & but Matlab shows a waring so I did not actually tested it. Now I run it and it goes through without an error but the result looks like Dca with no part of Sca and no color changes in the overlapping region of the two masks. – Günter Bachelier Jun 07 '19 at 07:47
  • You know, this would be so much easier if you posted a [mre] with sample input and your desired output (added to the question with [edit], not in comments) along with your code. It's really hard to tell what your expected result is. – beaker Jun 07 '19 at 19:12

1 Answers1

0

A freelancer.com project delivered the following proposal, which is about 10+ times faster than an arrayfun version but 5+ times slower than one would expect if Matlab could directly uses the syntax in the SVG standard like in most of the other cases:

if strcmp(compo_meth, 'color-dodge') == 1
    rc = (Sca == Sa) & (Dca == 0);
    Dca(rc) = (1 - Da(rc)) .* Sca(rc);
    rc1 = (Sca == Sa) & (Dca ~= 0);
    Dca(rc1) = Sa(rc1) .* Da(rc1) + (1 - Da(rc1)) .* Sca(rc1) + (1 - Sa(rc1)) .* Dca(rc1);
    rc2 = (Sca < Sa);
    Dca(rc2) = Sa(rc2) .* Da(rc2) .* min(1, Dca(rc2)./Da(rc2) .* Sa(rc2)./(Sa(rc2) - Sca(rc2)));
    Da = Sa + Da - Sa .* Da;
end