-
Notifications
You must be signed in to change notification settings - Fork 46
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
Support split encode/decoder mode, "mode B" #27
Conversation
Also, *maybe* should switch to ecc_block_size=162 for 5x5, it lends itself to more ecc flexibility.
However, in this case what I want to do is use kmeans not just for analysis, but actually for the color decode itself...
Also, ditch the "relative_color_diff", I don't think it helps.
Also, some experimental stuff with the color scaling/threshholding
32 is a bit low...
…imbar Also *maybe* will be useful for the color decode (this is the real reason to go through the trouble)
This is *mostly* analogous to what libcimbar is doing. (just much less efficient)
The code is a bit messy, alas
This will (if it works) allow us to use the fountain header color cells (which are interleaved through the image) as a sort of color key/legend for the full decode step. There is currently a bug, though...
This should be everything we need.
A lot of permutations to test, still....
one for the "center" area (determined by distance from middle of image), one for the "edges" (everything else) Quickly running into an adversarial worst case -- the default encode_id is currently `0`, which results in a *lot* of 0 (green) color tiles and very few of any other color. Meaning that we just don't have much data for the other colors to safely split among multiple sections.
-- not sure what to do when the sampling data is bad, I *think* we might just want to bail. (has implications for 8-color though (: )
Inclined to think the two-pass may be better, though
+ stick with bitstring 3.1.9 until I can look at how the API changed in v4
Pull Request Test Coverage Report for Build 7999867768Details
💛 - Coveralls |
@@ -22,10 +23,10 @@ def possible_colors(dark, bits=0): | |||
] | |||
elif dark and bits < 3: | |||
colors = [ | |||
(0, 0xFF, 0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll need to add back the old color set in a follow up PR. I'm thinking of merging the dark
flag into something like a color_mode
flag. So we'd have 0 for the original color arrangement, 1 for this, and 100 (or something) for light mode.
# probably some scaling will be good. | ||
def scale_color(self, r, g, b): | ||
if self.disable_color_scaling: | ||
return r, g, b |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code base continues to be a victim of being used for prototyping things. This variable and logic can probably be deleted...
... unless it ends up being really useful, so we'd better keep it 😶
|
||
def _correct_all_colors(self, r, g, b, sector): | ||
if isinstance(self.ccm, list): | ||
ccm = self.ccm[sector] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, this is another "well what if we want to..." -- in this case, using the naive ccm based on a single color average (white) followed by a von kries transform, then feeding those corrected values into the Moore-Penrose based CCM, then smashing the resulting CCMs together for one king of all CCMs.
Anyway I don't think this one is that useful at this point, and it's about as silly as that explanation makes it sound. So this one will probably get removed.
@@ -1,4 +1,5 @@ | |||
bitstring | |||
bitstring==3.1.9 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point bitstring changed something and broke my stuff. I don't think it's a big deal, but it does need some attention.
This needs some cleanup. In any event, 0,1,3 are the options that matter for now. I might put 2 (kmeans clustering) back at some point.
import bitstring | ||
from bitstring import Bits, BitStream | ||
|
||
# it'd be nice to use the frame id as well, but sometimes we skip frames. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth noting: I'm currently ignoring this advice in libcimbar
and using the frame_id anyway. It's only going to mess up one decode, what's the harm? 😬
(TODO: do the math in libcimbar to not mess up that one frame)
else: # cc_setting == 3,5 | ||
ct.ccm = der.dot(ct.ccm) | ||
|
||
if splits: # 6,7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to come back to this at some point to see if there's something I missed. There's more work to be done here.
if ct.ccm is None or cc_setting == 4: | ||
ct.ccm = der | ||
else: # cc_setting == 3,5 | ||
ct.ccm = der.dot(ct.ccm) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This .dot
nonsense needs to go away, probably. (merging the CCMs together)
yield -1, None | ||
|
||
# state_info can be set at any time, but it will probably be set by the caller *after* the empty yield above | ||
if state_info.get('color_correct') == 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When this got refactored, the kmeans code got left behind. It should probably make a comeback, because (1) it works, (2) it doesn't require a fountain decode to work, (3) it'll be useful as a comparison.
Just a bit of minor cleanup
Pull Request Test Coverage Report for Build 7999779292Details
💛 - Coveralls |
Pull Request Test Coverage Report for Build 7999635392Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
counterpart to sz3/libcimbar#91 (and arguably sz3/libcimbar#92, though that one is low on code changes)
This changeset reflects various experiments to that end:
should we continue to use the naive CCM in addition to a smarter method?
what should the "smarter method" be? The
colour-science
package uses a Moore–Penrose inverse of observed vs ideal color values. That seemed like a good starting point, but there were other questions:disclaimer: all of these methods are heuristics. Evaluation was done against real world captures of cimbar images (from different camera + in different conditions) to try to pick the best one, but simplicity of implementation also factored in. The main questions I was trying to answer were:
The answers, as far as I could tell, are (1) no and (2) probably no. (2) can be re-evaluated at any time, since it is purely implementation side.
The end result of all this is new 4-color 8x8 format called
Mode B
(named after I made these changes, so currently a libcimbar-only name. I'll update this repo to use that convention eventually. Probably.)
Mode B is shorthand for "8x8, 4-color, 30/155ecc, 12 fountain blocks of 625 bytes apiece, split color and symbol decodes, using color set 1"
whereas
Mode 4C
(the original format) would be "8x8, 4-color, 30/155ecc, 10 fountain blocks of 750 bytes apiece, interleaved color and symbol decodes, using color set 0"... which is why I decided to call it "B" and "C".