Reducing matrix size in 2D using KNN











up vote
0
down vote

favorite












I have a large binary matrix. I want to reduce the size of this matrix by using knn-approximation. What my idea is to cluster the matrix in groups of 4 neighbors and replace the group with a 1, if the number of 1s in the group is greater than or equal to the number of zeros.



To be concrete, let the matrix be



1 0 0 1 0 
0 1 1 0 0
1 1 0 0 0
0 1 1 1 0
0 0 1 1 0
1 0 0 1 0


First I want to create neighborhood group as



1 0 |0 1| 0| 
0 1 |1 0| 0|
------------
1 1 |0 0| 0|
0 1 |1 1| 0|
------------
0 0 |1 1| 0|
------------


and then the final matrix I want to generate is



1 1 0
1 1 0
0 1 0


by replacing the group with the majority score. How can I efficiently do this is MATLAB?










share|improve this question
























  • Several questions: 1) Will your matrix always divide with a remainder into blocks? 2) Which MATLAB version are you using? 3) Do you have the image processing toolbox? 4) Did you try something already (e.g. mat2cell)?
    – Dev-iL
    Nov 11 at 8:37












  • 1) nope. as in figure, the remainder is grouped into the remaining size. 2) I am using version 2016b. 3) Yes, I have image processing toolbox. 4) nope. i did not try anything other than splitting using loop.
    – Shew
    Nov 11 at 8:40















up vote
0
down vote

favorite












I have a large binary matrix. I want to reduce the size of this matrix by using knn-approximation. What my idea is to cluster the matrix in groups of 4 neighbors and replace the group with a 1, if the number of 1s in the group is greater than or equal to the number of zeros.



To be concrete, let the matrix be



1 0 0 1 0 
0 1 1 0 0
1 1 0 0 0
0 1 1 1 0
0 0 1 1 0
1 0 0 1 0


First I want to create neighborhood group as



1 0 |0 1| 0| 
0 1 |1 0| 0|
------------
1 1 |0 0| 0|
0 1 |1 1| 0|
------------
0 0 |1 1| 0|
------------


and then the final matrix I want to generate is



1 1 0
1 1 0
0 1 0


by replacing the group with the majority score. How can I efficiently do this is MATLAB?










share|improve this question
























  • Several questions: 1) Will your matrix always divide with a remainder into blocks? 2) Which MATLAB version are you using? 3) Do you have the image processing toolbox? 4) Did you try something already (e.g. mat2cell)?
    – Dev-iL
    Nov 11 at 8:37












  • 1) nope. as in figure, the remainder is grouped into the remaining size. 2) I am using version 2016b. 3) Yes, I have image processing toolbox. 4) nope. i did not try anything other than splitting using loop.
    – Shew
    Nov 11 at 8:40













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have a large binary matrix. I want to reduce the size of this matrix by using knn-approximation. What my idea is to cluster the matrix in groups of 4 neighbors and replace the group with a 1, if the number of 1s in the group is greater than or equal to the number of zeros.



To be concrete, let the matrix be



1 0 0 1 0 
0 1 1 0 0
1 1 0 0 0
0 1 1 1 0
0 0 1 1 0
1 0 0 1 0


First I want to create neighborhood group as



1 0 |0 1| 0| 
0 1 |1 0| 0|
------------
1 1 |0 0| 0|
0 1 |1 1| 0|
------------
0 0 |1 1| 0|
------------


and then the final matrix I want to generate is



1 1 0
1 1 0
0 1 0


by replacing the group with the majority score. How can I efficiently do this is MATLAB?










share|improve this question















I have a large binary matrix. I want to reduce the size of this matrix by using knn-approximation. What my idea is to cluster the matrix in groups of 4 neighbors and replace the group with a 1, if the number of 1s in the group is greater than or equal to the number of zeros.



To be concrete, let the matrix be



1 0 0 1 0 
0 1 1 0 0
1 1 0 0 0
0 1 1 1 0
0 0 1 1 0
1 0 0 1 0


First I want to create neighborhood group as



1 0 |0 1| 0| 
0 1 |1 0| 0|
------------
1 1 |0 0| 0|
0 1 |1 1| 0|
------------
0 0 |1 1| 0|
------------


and then the final matrix I want to generate is



1 1 0
1 1 0
0 1 0


by replacing the group with the majority score. How can I efficiently do this is MATLAB?







matlab matrix binary-data knn downsampling






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 at 9:10









Dev-iL

16.3k64074




16.3k64074










asked Nov 11 at 8:25









Shew

4971516




4971516












  • Several questions: 1) Will your matrix always divide with a remainder into blocks? 2) Which MATLAB version are you using? 3) Do you have the image processing toolbox? 4) Did you try something already (e.g. mat2cell)?
    – Dev-iL
    Nov 11 at 8:37












  • 1) nope. as in figure, the remainder is grouped into the remaining size. 2) I am using version 2016b. 3) Yes, I have image processing toolbox. 4) nope. i did not try anything other than splitting using loop.
    – Shew
    Nov 11 at 8:40


















  • Several questions: 1) Will your matrix always divide with a remainder into blocks? 2) Which MATLAB version are you using? 3) Do you have the image processing toolbox? 4) Did you try something already (e.g. mat2cell)?
    – Dev-iL
    Nov 11 at 8:37












  • 1) nope. as in figure, the remainder is grouped into the remaining size. 2) I am using version 2016b. 3) Yes, I have image processing toolbox. 4) nope. i did not try anything other than splitting using loop.
    – Shew
    Nov 11 at 8:40
















Several questions: 1) Will your matrix always divide with a remainder into blocks? 2) Which MATLAB version are you using? 3) Do you have the image processing toolbox? 4) Did you try something already (e.g. mat2cell)?
– Dev-iL
Nov 11 at 8:37






Several questions: 1) Will your matrix always divide with a remainder into blocks? 2) Which MATLAB version are you using? 3) Do you have the image processing toolbox? 4) Did you try something already (e.g. mat2cell)?
– Dev-iL
Nov 11 at 8:37














1) nope. as in figure, the remainder is grouped into the remaining size. 2) I am using version 2016b. 3) Yes, I have image processing toolbox. 4) nope. i did not try anything other than splitting using loop.
– Shew
Nov 11 at 8:40




1) nope. as in figure, the remainder is grouped into the remaining size. 2) I am using version 2016b. 3) Yes, I have image processing toolbox. 4) nope. i did not try anything other than splitting using loop.
– Shew
Nov 11 at 8:40












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










Initially I tried getting it to work using imresize but couldn't quite get it without "hacks" (it was off by 1 value in all my "proper" attempts).



imresize(M, ceil(size(M)/2), 'bilinear') >= 0.4 % This works but is hacky and not recommended!


However, I can think of a way to solve this using 2D convolution. Note that I pad the array (which requires a toolbox) in order to simplify the indexing stage at the end:



function C = q53247013(M)

if nargin < 1

M = [
1 0 0 1 0
0 1 1 0 0
1 1 0 0 0
0 1 1 1 0
0 0 1 1 0
1 0 0 1 0];

end

% Constants:
BLK_SZ = 2;
A = ones(BLK_SZ);

% Pad array if needed (note: this WILL require modification if BLK_SZ > 2 ):
padBottom = rem(size(M,BLK_SZ),1);
padRight = rem(size(M,BLK_SZ),2);
M = padarray(M, [padBottom, padRight], 'replicate', 'post');

% Perform convolution:
C = conv2(M, A, 'valid') >= ceil(BLK_SZ^2 / 2);

% Remove every other row and column:
C = C(1:2:end, 1:2:end);


Another alternative is the blockproc function:



C = blockproc(M, [2 2], @(x)sum(x.data(:))) >= 2;





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53247013%2freducing-matrix-size-in-2d-using-knn%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted










    Initially I tried getting it to work using imresize but couldn't quite get it without "hacks" (it was off by 1 value in all my "proper" attempts).



    imresize(M, ceil(size(M)/2), 'bilinear') >= 0.4 % This works but is hacky and not recommended!


    However, I can think of a way to solve this using 2D convolution. Note that I pad the array (which requires a toolbox) in order to simplify the indexing stage at the end:



    function C = q53247013(M)

    if nargin < 1

    M = [
    1 0 0 1 0
    0 1 1 0 0
    1 1 0 0 0
    0 1 1 1 0
    0 0 1 1 0
    1 0 0 1 0];

    end

    % Constants:
    BLK_SZ = 2;
    A = ones(BLK_SZ);

    % Pad array if needed (note: this WILL require modification if BLK_SZ > 2 ):
    padBottom = rem(size(M,BLK_SZ),1);
    padRight = rem(size(M,BLK_SZ),2);
    M = padarray(M, [padBottom, padRight], 'replicate', 'post');

    % Perform convolution:
    C = conv2(M, A, 'valid') >= ceil(BLK_SZ^2 / 2);

    % Remove every other row and column:
    C = C(1:2:end, 1:2:end);


    Another alternative is the blockproc function:



    C = blockproc(M, [2 2], @(x)sum(x.data(:))) >= 2;





    share|improve this answer



























      up vote
      1
      down vote



      accepted










      Initially I tried getting it to work using imresize but couldn't quite get it without "hacks" (it was off by 1 value in all my "proper" attempts).



      imresize(M, ceil(size(M)/2), 'bilinear') >= 0.4 % This works but is hacky and not recommended!


      However, I can think of a way to solve this using 2D convolution. Note that I pad the array (which requires a toolbox) in order to simplify the indexing stage at the end:



      function C = q53247013(M)

      if nargin < 1

      M = [
      1 0 0 1 0
      0 1 1 0 0
      1 1 0 0 0
      0 1 1 1 0
      0 0 1 1 0
      1 0 0 1 0];

      end

      % Constants:
      BLK_SZ = 2;
      A = ones(BLK_SZ);

      % Pad array if needed (note: this WILL require modification if BLK_SZ > 2 ):
      padBottom = rem(size(M,BLK_SZ),1);
      padRight = rem(size(M,BLK_SZ),2);
      M = padarray(M, [padBottom, padRight], 'replicate', 'post');

      % Perform convolution:
      C = conv2(M, A, 'valid') >= ceil(BLK_SZ^2 / 2);

      % Remove every other row and column:
      C = C(1:2:end, 1:2:end);


      Another alternative is the blockproc function:



      C = blockproc(M, [2 2], @(x)sum(x.data(:))) >= 2;





      share|improve this answer

























        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        Initially I tried getting it to work using imresize but couldn't quite get it without "hacks" (it was off by 1 value in all my "proper" attempts).



        imresize(M, ceil(size(M)/2), 'bilinear') >= 0.4 % This works but is hacky and not recommended!


        However, I can think of a way to solve this using 2D convolution. Note that I pad the array (which requires a toolbox) in order to simplify the indexing stage at the end:



        function C = q53247013(M)

        if nargin < 1

        M = [
        1 0 0 1 0
        0 1 1 0 0
        1 1 0 0 0
        0 1 1 1 0
        0 0 1 1 0
        1 0 0 1 0];

        end

        % Constants:
        BLK_SZ = 2;
        A = ones(BLK_SZ);

        % Pad array if needed (note: this WILL require modification if BLK_SZ > 2 ):
        padBottom = rem(size(M,BLK_SZ),1);
        padRight = rem(size(M,BLK_SZ),2);
        M = padarray(M, [padBottom, padRight], 'replicate', 'post');

        % Perform convolution:
        C = conv2(M, A, 'valid') >= ceil(BLK_SZ^2 / 2);

        % Remove every other row and column:
        C = C(1:2:end, 1:2:end);


        Another alternative is the blockproc function:



        C = blockproc(M, [2 2], @(x)sum(x.data(:))) >= 2;





        share|improve this answer














        Initially I tried getting it to work using imresize but couldn't quite get it without "hacks" (it was off by 1 value in all my "proper" attempts).



        imresize(M, ceil(size(M)/2), 'bilinear') >= 0.4 % This works but is hacky and not recommended!


        However, I can think of a way to solve this using 2D convolution. Note that I pad the array (which requires a toolbox) in order to simplify the indexing stage at the end:



        function C = q53247013(M)

        if nargin < 1

        M = [
        1 0 0 1 0
        0 1 1 0 0
        1 1 0 0 0
        0 1 1 1 0
        0 0 1 1 0
        1 0 0 1 0];

        end

        % Constants:
        BLK_SZ = 2;
        A = ones(BLK_SZ);

        % Pad array if needed (note: this WILL require modification if BLK_SZ > 2 ):
        padBottom = rem(size(M,BLK_SZ),1);
        padRight = rem(size(M,BLK_SZ),2);
        M = padarray(M, [padBottom, padRight], 'replicate', 'post');

        % Perform convolution:
        C = conv2(M, A, 'valid') >= ceil(BLK_SZ^2 / 2);

        % Remove every other row and column:
        C = C(1:2:end, 1:2:end);


        Another alternative is the blockproc function:



        C = blockproc(M, [2 2], @(x)sum(x.data(:))) >= 2;






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 11 at 9:27

























        answered Nov 11 at 9:05









        Dev-iL

        16.3k64074




        16.3k64074






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53247013%2freducing-matrix-size-in-2d-using-knn%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Xamarin.iOS Cant Deploy on Iphone

            Glorious Revolution

            Dulmage-Mendelsohn matrix decomposition in Python