Access behaviour (Getting a sub‐area of an image) - cocoa-xu/evision GitHub Wiki

  • Access.fetch/2 examples:

    iex> img = Evision.imread("test/qr_detector_test.png")
    %Evision.Mat{
      channels: 3,
      dims: 2,
      type: {:u, 8},
      raw_type: 16,
      shape: {300, 300, 3},
      ref: #Reference<0.809884129.802291734.78316>
    }
    
    # Same behaviour as Nx. 
    # Also, img[0] gives the same result as img[0](/cocoa-xu/evision/wiki/0)
    # For this example, they are both equvilent of img[0, :all, :all](/cocoa-xu/evision/wiki/0,-:all,-:all)
    iex> img[0](/cocoa-xu/evision/wiki/0)
    %Evision.Mat{
      channels: 3,
      dims: 2,
      type: {:u, 8},
      raw_type: 16,
      shape: {1, 300, 3},
      ref: #Reference<0.809884129.802291731.77296>
    }
    
    # same as img[0..100, 50..200, :all](/cocoa-xu/evision/wiki/0..100,-50..200,-:all)
    # however, currently we only support ranges with step size 1
    #
    # **IMPORTANT NOTE**
    #
    # also, please note that we are using Elixir.Range here
    # and Elixir.Range is **inclusive**, i.e, [start, end] 
    # while cv::Range `{integer(), integer()}` is `[start, end)`
    # the difference can be observed in the `shape` field
    iex> img[0..100, 50..200](/cocoa-xu/evision/wiki/0..100,-50..200)
    %Evision.Mat{
      channels: 3,
      dims: 2,
      type: {:u, 8},
      raw_type: 16,
      shape: {101, 151, 3},
      ref: #Reference<0.809884129.802291731.77297>
    }
    iex> img[{0, 100}, {50, 200}](/cocoa-xu/evision/wiki/{0,-100},-{50,-200})
    %Evision.Mat{
      channels: 3,
      dims: 2,
      type: {:u, 8},
      raw_type: 16,
      shape: {100, 150, 3},
      ref: #Reference<0.809884129.802291731.77297>
    }
    
    # for this example, the result is the same as `Evision.extractChannel(img, 0)`
    iex> img[:all, :all, 0](/cocoa-xu/evision/wiki/:all,-:all,-0)
    %Evision.Mat{
      channels: 1,
      dims: 2,
      type: {:u, 8},
      raw_type: 0,
      shape: {300, 300},
      ref: #Reference<0.809884129.802291731.77298>
    }
    iex> img[:all, :all, 0..1](/cocoa-xu/evision/wiki/:all,-:all,-0..1)
    %Evision.Mat{
      channels: 2,
      dims: 2,
      type: {:u, 8},
      raw_type: 8,
      shape: {300, 300, 2},
      ref: #Reference<0.809884129.802291731.77299>
    }
    
    # when index is out of bounds
    iex> img[:all, :all, 42](/cocoa-xu/evision/wiki/:all,-:all,-42)
    {:error, "index 42 is out of bounds for axis 2 with size 3"}
    
    # it works the same way for any dimensional Evision.Mat
    iex> mat = Evision.Mat.ones({10, 10, 10, 10, 10}, :u8)
    iex> mat[1..7, :all, 2..6, 3..9, :all](/cocoa-xu/evision/wiki/1..7,-:all,-2..6,-3..9,-:all)
    %Evision.Mat{
      channels: 1,
      dims: 5,
      type: {:u, 8},
      raw_type: 0,
      shape: {7, 10, 5, 7, 10},
      ref: #Reference<0.3015448455.3766878228.259075>
    }
    
  • Access.get_and_update/3 examples:

    iex> mat = Evision.Mat.zeros({5, 5}, :u8)
    iex> Evision.Nx.to_nx(mat)
    #Nx.Tensor<
      u8[5][5]
      Evision.Backend
      [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0]
      ]
    >
    iex> {old, new} = Evision.Mat.get_and_update(mat, [1..3, 1..3], fn roi ->
        {roi, Nx.broadcast(Nx.tensor(255, type: roi.type), roi.shape)}
    end)
    iex> Evision.Nx.to_nx(new)
    #Nx.Tensor<
      u8[5][5]
      Evision.Backend
      [
        [0, 0, 0, 0, 0],
        [0, 255, 255, 255, 0],
        [0, 255, 255, 255, 0],
        [0, 255, 255, 255, 0],
        [0, 0, 0, 0, 0]
      ]
    >