Error: The variable Calls in a parfor cannot be classified.
    조회 수: 3 (최근 30일)
  
       이전 댓글 표시
    
I am trying to use the "parfor" command from the parallel processing toolbox in an app that I am designing, but I am getting some errors. This is my first time using the parallel processing toolbox and I am not really familiar with the common errors. could you help me out?
%% Quail Call Detection
parfor i = 1:4
    Ispec= app.Spectrograms{i};
    if ~isempty(app.Spectrograms{i})
        spec_len=size(Ispec,2);
        spec_width=size(Ispec,1);
        %     figure();imshow(Ispec)
        band=round((spec_width-temp_width)/3);
        spec_seg_size=ceil(spec_len/30);
        call_candidates=[];
        %call_locations=[];
        no_seg=ceil(spec_len/spec_seg_size)*2-1;
        for s=1:no_seg
            spec_seg=Ispec(band:end-band,(s-1)*ceil(spec_seg_size/2)+1:min((s-1)*ceil(spec_seg_size/2)+1+spec_seg_size,spec_len));
            cc=xcorr2(spec_seg,template);
            cc_signal=mat2gray(max(cc));
            cc_signal=cc_signal(round(temp_length/2)-1:end-round(temp_length/2));
            TF = islocalmax(cc_signal,'MinProminence',0.25,'ProminenceWindow',temp_length/2);
            locs=find(TF);
            call=(((s-1)*ceil(spec_seg_size/2)+1)+locs)';
            call_candidates=[call_candidates;call];
            %         figure;imshow(spec_seg)
            %         x=1:length(cc_signal);
            %         figure;plot(x,cc_signal,x(TF),cc_signal(TF),'r*')
            %         waitforbuttonpress;
        end
        if ~isempty(call_candidates)
            if length(call_candidates)>1
                [L,n]=bwlabel(squareform(pdist(call_candidates))<temp_length/2,4);
                for k=1:n
                    [rows,~]=find(L==k);
                    rows=unique(rows);
                    spec_seg=Ispec(band:end-band,max(call_candidates(min(rows))-...
                        round(temp_length/2),1):min(call_candidates(min(rows))+round(temp_length/2),spec_len));
                    cc=xcorr2(spec_seg,template);
                    cc_signal=mat2gray(max(cc));
                    cc_signal=cc_signal(round(temp_length/2)-1:end-round(temp_length/2));
                    TF = islocalmax(cc_signal,'MinProminence',0.25,'ProminenceWindow',temp_length/2);
                    location=find(TF);
                    if call_candidates(min(rows)) <round(temp_length/2)
                        call=(time(1)+(spec_duration/spec_len)*location);
                        Calls{i}=[Calls{i};call'];
                        %call_locations=[call_locations;location'];
                    else
                        call=(time(1)+(spec_duration/spec_len)*(call_candidates(min(rows))+location-round(temp_length/2)));
                        Calls{i}=[Calls{i};call'];
                        %call_locations=[call_locations;call_candidates(min(rows))+location'-round(temp_length/2)];
                    end
                    %                 figure;imshow(spec_seg)
                    %                 x=1:length(cc_signal);
                    %                 figure;plot(x,cc_signal,x(TF),cc_signal(TF),'r*')
                    %                 waitforbuttonpress;
                end
            else
                spec_seg=Ispec(band:end-band,max(call_candidates(1)-round(temp_length/2),1):min(call_candidates(1)+round(temp_length/2),spec_len));
                cc=xcorr2(spec_seg,template);
                cc_signal=mat2gray(max(cc));
                cc_signal=cc_signal(round(temp_length/2)-1:end-round(temp_length/2));
                TF = islocalmax(cc_signal,'MinProminence',0.25,'ProminenceWindow',temp_length/2);
                location=find(TF);
                if call_candidates(1) <round(temp_length/2)
                    call=(time(1)+(spec_duration/spec_len)*location)';
                    Calls{i}=[Calls{i};call'];
                    %call_locations=[call_locations;location'];
                else
                    call=(time(1)+(spec_duration/spec_len)*(call_candidates(1)+location-round(temp_length/2)));
                    Calls{i}=[Calls{i};call'];
                    %call_locations=[call_locations;max(call_candidates(1)+location'-round(temp_length/2),1)];
                end
                %             figure;imshow(spec_seg)
                %             x=1:length(cc_signal);
                %             figure;plot(x,cc_signal,x(TF),cc_signal(TF),'r*')
                %             waitforbuttonpress;
            end
        end
        % For Drawing Bounding Boxes
        %pos{i} = [Calls{i} 1200*ones(length(Calls{i}),1) ...
        %    0.5*ones(length(Calls{i}),1) 1900*ones(length(Calls{i}),1)];
    %% Place Call Times into corresponding variables
    CallA = Calls{1};
    CallA(find(CallA==0)) = [];
    CallB = Calls{2};
    CallB(find(CallB==0)) = [];
    CallC = Calls{3};
    CallC(find(CallC==0)) = [];
    CallD = Calls{4};
    CallD(find(CallD==0)) = [];
     %% Drawing Lines on Calls
     if app.OffButton.Value == 1 && strcmp(app.ModeSwitch.Value,"Online")
         for row = 1:size(Calls{1},1)
             line(app.UIAxes,Calls{1}(row,:)*ones(1,length(app.F)),app.F,'Color','red','LineWidth',1.5);
         end
         for row = 1:size(Calls{2},1)
             line(app.UIAxes_2,Calls{2}(row,:)*ones(1,length(app.F)),app.F,'Color','red','LineWidth',1.5);
         end
         for row = 1:size(Calls{3},1)
             line(app.UIAxes_3,Calls{3}(row,:)*ones(1,length(app.F)),app.F,'Color','red','LineWidth',1.5);
         end
         for row = 1:size(Calls{4},1)
             line(app.UIAxes_4,Calls{4}(row,:)*ones(1,length(app.F)),app.F,'Color','red','LineWidth',1.5);
         end
     end
    end 
end
end
I am getting the following error:
Error: The variable Calls in a parfor cannot be classified.
Please let me know if you needed any exrta information.
댓글 수: 0
채택된 답변
  Walter Roberson
      
      
 2020년 5월 31일
            %%Place Call Times into corresponding variables
    CallA = Calls{1};
Earlier you index Calls{i} where i is the parfor variable. Loops are not done in order, so when you go to process i=4, producing Calls{4}, then Calls{1} might not be ready yet. Inside parfor if you index a variable with the parfor index then you cannot refer to the same variable indexed at any constant index or any index that is not derived from the parfor variable.
Please also note that inside a worker, you cannot make graphics changes to the display.
It looks to me as if all that drawing code should be moved after the parfor loop.
댓글 수: 2
  Walter Roberson
      
      
 2020년 5월 31일
				    Ispec= app.Spectrograms{i};
Before the loop, extract  app.Spectrograms into a separate variable that is not within app, such as 
    Spectrograms = app.Spectrograms;
and use that variable instead of app.Spectrograms .
That is, do not have any reference to app inside your parfor execution.
추가 답변 (0개)
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

