6by9 / lens_shading

Lens shading analysis tool
19 stars 9 forks source link

Lens shading table not taking effect #4

Open abingham opened 3 years ago

abingham commented 3 years ago

I've been trying to apply lens shading to my rpi camera, and - while the ultimate mmal_port_parameter_set() call is returning a successful result - I never see any actual correction to subsequent images. Here's the program I've got that updates the camera (it's C++ based on the sketch you provide in the README):

#include <exception>
#include <iostream>
#include <string>

#include <interface/mmal/mmal.h>
#include <interface/mmal/mmal_component.h>
#include <interface/mmal/mmal_logging.h>
#include <interface/mmal/mmal_port.h>
#include <interface/mmal/util/mmal_default_components.h>
#include <interface/vcos/vcos.h>
#include <interface/vcos/vcos_logging.h>
#include <interface/vcsm/user-vcsm.h>

class Camera {
public:
      Camera(const std::string& component_name) : camera_(0) {
            std::cout << "Component name: " << component_name << "\n";
            MMAL_STATUS_T status = mmal_component_create(component_name.c_str(), &camera_);
            if (status != MMAL_SUCCESS)
            {
                  vcos_log_error("Failed to create camera component");
                  throw std::bad_alloc();
            }
      }

      ~Camera() {
            if (camera_) {
                  mmal_component_destroy(camera_);
            }
      }

      MMAL_COMPONENT_T* ptr() const {
            return camera_;
      }

private:
      MMAL_COMPONENT_T* camera_;
};

class VCSMBlock {
public:
      VCSMBlock(unsigned int size, const std::string& name) 
            : handle_(vcsm_malloc(size, name.c_str())) 
            {
                  if (0 == handle_) {
                        vcos_log_error("Failed to allocate vcsm block");
                        throw std::bad_alloc();
                  }
            }

      ~VCSMBlock() {
            vcsm_free(handle_);
      }

      int handle() const {
            return handle_;
      }

private:
      int handle_;
};

class VCSMLock {
public:
      VCSMLock(int handle)
            : handle_(handle)
            , block_(vcsm_lock(handle)) 
            {
                  if (NULL == block_) {
                        vcos_log_error("Failed to lock vcsm block");
                        throw std::bad_alloc();
                  }

            }

      ~VCSMLock() {
            vcsm_unlock_hdl(handle_);
      }

      void* block() const {
            return block_;
      }

private:
      int handle_;
      void* block_;
}; 

namespace {
      #include "ls_table.h"
}

int main(int argc, char **argv)
{
      // Register our application with the logging system
      vcos_log_register("update_table", VCOS_LOG_CATEGORY);

      std::string camera_name(MMAL_COMPONENT_DEFAULT_CAMERA);
      if (argc > 1) {
            camera_name = argv[1];
      }

      Camera camera(camera_name);

      MMAL_PARAMETER_LENS_SHADING_T ls = {{MMAL_PARAMETER_LENS_SHADING_OVERRIDE, sizeof(MMAL_PARAMETER_LENS_SHADING_T)}};

      ls.enabled = MMAL_TRUE;
      ls.grid_cell_size = 64;
      ls.grid_width = ls.grid_stride = grid_width;
      ls.grid_height = grid_height;
      ls.ref_transform = ref_transform;

      VCSMBlock grid(ls.grid_stride * ls.grid_height * 4, "ls_grid");
      ls.mem_handle_table = vcsm_vc_hdl_from_hdl(grid.handle());

      if (0 == ls.mem_handle_table) {
            vcos_log_error("Failed to get lens shading handle");
            return 1;
      }

      {
            VCSMLock grid_lock(grid.handle());
            memcpy(grid_lock.block(), ls_grid, vcos_min(sizeof(ls_grid), ls.grid_stride * ls.grid_height * 4));
      }

      int status = mmal_port_parameter_set(camera.ptr()->control, &ls.hdr);
      if (status != MMAL_SUCCESS) {
            vcos_log_error("Failed to set lens shading parameters - %d", status);
            return 1;
      }

      return 0;
}

It's using the ls_table.h generated by lens_shading_analyse. All I do is something like this:

raspistill --raw -o image.orig.jpg
./lens_shading_analyse image.orig.jpg
make  # compiles the above program to update_program
./update_table
raspistill --raw -o image.jpg

My expectation is that image.jpg will have been taken using the lens shading table produced by lens_shading_analyse, but the image.orig.jpg and image.jpg always look identical.

Am I just doing something boneheaded? Is it perhaps possible that I've actually disabled lens shading support somehow? Should I even expect lens shading to work?

Here's some information about my system:

Any guidance would be deeply appreciated.