Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how can i change the variable(interleave_blocks and interleave_partitions) in config.cpp? #72

Closed
lhx0217 opened this issue May 22, 2023 · 12 comments

Comments

@lhx0217
Copy link

lhx0217 commented May 22, 2023

I noticed that the value of interleave_blocks is 155, with 30 of them being ecc_ bytes, 155 can be evenly divided by 9300, but I cannot receive it properly after changing the interleave_blocks to 100. I also don't quite understand the meaning of interleave_partitions.

@lhx0217
Copy link
Author

lhx0217 commented May 22, 2023

Due to the resolution issue of the camera, I am trying to reduce the size of the generated image, but I have not found the constraint relationship between these parameters. Would you please explain it?
Regards.

@sz3
Copy link
Owner

sz3 commented May 23, 2023

This branch will probably be helpful (I'm hoping to merge it to master soon): https://github.com/sz3/libcimbar/tree/bugfix-improve-and-5x5

These are the parameters that are easy(ish) to play with: https://github.com/sz3/libcimbar/blob/bugfix-improve-and-5x5/src/lib/cimb_translator/GridConf.h#L21-L29

The process is:

  • determine a suitable cells_per_col and image_size setting for your configuration: https://github.com/sz3/libcimbar/blob/bugfix-improve-and-5x5/src/lib/cimb_translator/GridConf.h#L29. The calculation for the current 8x8 is 112*9 == 1008 + 16px of padding, which gives us 1024.
  • plug your numbers into total_cells(): https://github.com/sz3/libcimbar/blob/bugfix-improve-and-5x5/src/lib/cimb_translator/Config.cpp#L7-L10
    • e.g. for 112x112 8x8, it's 1550.
  • get the factorization of that total cells number, and ideally use a factor in the 150<x<=255 range as your ecc_block_size.
    • e.g. for 1550, it's 1, 2, 5, 10, 25, 31, 50, 62, 155, 310, 775, 1550. Of those, 155 is the only plausible choice.
    • If there are no good factors, try a different grid size. It's also possible to use a smaller number, e.g. ~100. But it must be a factor of total_cells().
  • now that you have total_cells() (and thus total_bytes) and an ecc_block_size, choose a default setting for ecc_bytes. I try to aim for ~19/20%, e.g. 30/155. Or 40/216.
  • you can now calculate your "payload" size -- that is, the size of the data after ecc. e.g. 9300*(155-30)/155 = 7500. fountain_chunks_per_frame() should neatly divide this.
    • 7500/10 = 750 byte chunks. Closer to 1000 is probably better, but this seems fine. (I'll probably add more configurability to make this easier)

More details that may or may not be helpful:

interleave_blocks is set to ecc_block_size for simplicity's sake, but conceptually they're different numbers. The important part is that they should neatly divide total_cells. ecc_block_size has an additional constraint that it must be <=255, since it's the (probably punctured) reed solomon block size.

Interleaving: The idea is that we are interleaving cells -- that is, instead of encoding bits 1-6 and then 7-12, we're encoding 1-6 then 61-66 (for example), then coming back to do 7-12 later. You can also think of it as the ecc blocks themselves being interleaved -- it's logically equivalent. interleave_blocks determines how many of these sections exist in the single image (frame). interleave_partitions divides the frame itself. That is, if it's set to 2, half the ecc/interleaved blocks will be confined entirely to the top half of the image, and half to the bottom.

interleave_partitions should be considered to be loosely coupled with fountain_chunks_per_frame(). That is, if we have 2 partitions and 10 fountain chunks, we will neatly have 5 in each half of the image. This is useful if, say, the entire top half of the image fails to decode, because the bottom half will be independent.

The constraints could technically be a little more flexible (e.g. technically if you do the math you might be able to get away with a factor of total bytes, e.g. 9300, not total cells, which is 1550), but in practice I've found the simpler/stricter constraints to be easier to reason about.


Anyway, let me know if any of that helps...

@sz3
Copy link
Owner

sz3 commented Jun 6, 2023

This should be much easier now both in this code base (#73), and particularly in the python code base (sz3/cimbar#25). Let me know if you still have questions!

@sz3 sz3 closed this as completed Jun 6, 2023
@lhx0217
Copy link
Author

lhx0217 commented Jun 6, 2023

Thanks for your reply, but I still encountered some issues, these are my parameters.
struct Conf8x8
{
static constexpr unsigned color_bits = 2;
static constexpr unsigned symbol_bits = 4;
static constexpr unsigned ecc_bytes = 10;
static constexpr unsigned ecc_block_size = 54;
static constexpr int image_size = 556;

	static constexpr unsigned cell_size = 8;
	static constexpr unsigned cell_offset = 8;
	static constexpr unsigned cells_per_col = 60;
};

I can't convert the cimbar code into a file correctly, where is the problem?
regards

@lhx0217
Copy link
Author

lhx0217 commented Jun 6, 2023

I also attempted to modify the image size in the previous version of libcimbar(0.5.12), but it was not successful as well.
Here is config.cpp, how should i modify it?
Config.txt

@lhx0217
Copy link
Author

lhx0217 commented Jun 6, 2023

image
I notice the numbers in Decoder.h is 1550 and 12400, I've changed them into 432 and 3456, but still cannot decode the cimbar code correctly, what should i do?

@lhx0217
Copy link
Author

lhx0217 commented Jun 6, 2023

I've tried the same parameter in the python version, it works correctly! How can i make it work in c++ version? @sz3
image

@mihaigalos
Copy link

Are you sure you've rebuilt the correct binary after the modification?

@sz3
Copy link
Owner

sz3 commented Jun 7, 2023

I suspect that rather than it working in the python version but not in the C++, what you're seeing is that it works with the base level of reedsolomon ecc, but not with the 2nd level of fountain (wirehair) ecc.

Some quick math, following what I wrote in the comment above:

  • num_cells() == 3456 . The relevant factors are 48, 54, 64, 72, 96, 108, 128, 144, 192, 216. You chose 54 for our ecc block size -- that's fine, if maybe a bit small.
  • total bytes is 3456×6÷8 == 2592. Payload size (after first level of ecc) will be [(2592/54)=48] ...48*44 == 2112.
    • 2112 is not divisible by fountain blocks (currently set as a constant "10"). So this ecc setting won't work as is.
    • if we set FOUNTAIN_BLOCKS to 4 or 6 or 8, those all divide 2112 nicely (and still gives us 2 interleave partitions). So that's one way to solve the problem.
  • we could also chose a different ecc block size. For example, a 29:144 (ecc:ecc_block_size) configuration gives us a payload of 2070, which clearly is divisible by 10 and should also work nicely. 🙂

@lhx0217
Copy link
Author

lhx0217 commented Jun 7, 2023

Thanks for your reply. I followed your instraction and modified the parameters as follows:
struct Conf8x8
{
static constexpr unsigned color_bits = 2;
static constexpr unsigned symbol_bits = 4;
static constexpr unsigned ecc_bytes = 29;
static constexpr unsigned ecc_block_size = 144;
static constexpr int image_size = 556;

	static constexpr unsigned cell_size = 8;
	static constexpr unsigned cell_offset = 8;
	static constexpr unsigned cells_per_col = 60;
};

But i still cannot get any outputfiles, do I need to make any other modifications?May I ask if this set of parameters can run successfully on your computer?Every time I rebuild the project using
cmake .
make -j7
make install

@sz3
Copy link
Owner

sz3 commented Jun 8, 2023

That config works for me. In full:

	struct Conf8x8
	{
		static constexpr unsigned color_bits = 2;
		static constexpr unsigned symbol_bits = 4;
		static constexpr unsigned ecc_bytes = 29;
		static constexpr unsigned ecc_block_size = 144;
		static constexpr int image_size = 556;

		static constexpr unsigned cell_size = 8;
		static constexpr unsigned cell_offset = 8;
		static constexpr unsigned cells_per_col = 60;
	};

To encode from the dist/bin/ directory (after make install):
./cimbar --encode ../../LICENSE -o /tmp/cppfount
^ there should be 3 output pngs. Here's the first one:
cppfount_0

Then, the decode, feeding all the output pngs from the previous step:
./cimbar -i /tmp/cppfount_*.png -o /tmp/

Output files will appear in /tmp/
/tmp//0.5387

@lhx0217
Copy link
Author

lhx0217 commented Jun 8, 2023

thank you very much!! I downloaded the code again and it worked correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants