adding multiple bitmap values for one key in dictionary with C#

巧了我就是萌 提交于 2019-12-07 07:00:44

问题


I had a dictionary to store pattern images for OCR purposes. I grabbed these bitmaps from dictionary and compared to ones that I cropped from image, if they matched => grabbed the key (OCR part is done).

The problem arises here. One Key should be represented by several different bitmaps (i.e. values). How do you add multiple bitmaps to the dictionary, to represent the same key?

that's how I used dictionary:

    Dictionary<string, Bitmap> lookup = new Dictionary<string, Bitmap>();
    lookup.Add("A", new Bitmap(@"C:\08\letters\1\a1.bmp", true));
    lookup.Add("A", new Bitmap(@"C:\08\letters\1\a2.bmp", true)); // Error will be here, because key A already exists for one Bitmap value.
    lookup.Add("a", new Bitmap(@"C:\08\letters\1\aa1.bmp", true));
    lookup.Add("B", new Bitmap(@"C:\08\letters\1\b1.bmp", true));

Now, to grab images and value I did following:

var target = lookup.ToList();
bitmap b1 = target[j].Value; //grab value
//if value = cropped bitmap => proceed
string key = target[j].Key; //grab key

How will this process change according to your solution?

P.s. I have heard of "System.Linq.Lookup(Of TKey, TElement)", but never used it before. Will this "lookup" help me solve my problem or is it a completely different tool? google doesn't know much about it either, so an example would be welcomed

please note, that I load dictionary only once, at program start, so it doesn't matter how fast adding is. Lookup, on the other side is what bothers me the most. I have 120 elements in two of my dictionaries, and according to this article http://www.dotnetperls.com/dictionary-time - Lookup in the List is much more slower, than in dictionary..

anyway I'll be doing some measures to test out how List solution that was suggested below - compares to Dictionary solution which I have right now and tell the results later, probably this evening.


回答1:


Lookup. It is basically a dictionary of Key to list of Values, instead of key to value.

lookup.Add("a", "123"); // creates 'a' key and adds '123' to it
lookup.Add("a", "456"); // adds '456' to existing 'a' key
lookup.Add("b", "000"); // creates 'b' key and adds '000' to it



回答2:


You can not add item into a dictionary with the same key. I think you are using the wrong data structure. I thing you might have to look into using a list<> instead. Like this:

var lookup=new List<KeyValuePair<string,Bitmap>>();
lookup.Add(new KeyValuePair<string,Bitmap>("A", new Bitmap(@"C:\08\letters\1\a1.bmp", true)));
lookup.Add(new KeyValuePair<string,Bitmap>("A", new Bitmap(@"C:\08\letters\1\a2.bmp", true)));
lookup.Add(new KeyValuePair<string,Bitmap>("a", new Bitmap(@"C:\08\letters\1\aa1.bmp", true)));
lookup.Add(new KeyValuePair<string,Bitmap>("B", new Bitmap(@"C:\08\letters\1\b1.bmp", true)));

The you can do this instead. Without doing ToList():

bitmap b1 = target[j].Value; //grab value
string key = target[j].Key; //grab key

Edit

But if you are doing a ToList() on a Dictionary then you are missing the point of having a Dictionary in the first place. Because then you are accessing the Dictionary anyway the list way. I can also see a problem doing a ToList() on a Dictionary because the sorting in a Dictionary is not as you insert them, it is by hash. That means that you can not be sure that Index 1 is index 1. You also have to take in considerations that the operation add on a Dictionary is not as effective as the add on a List. The god things with a Dictionary is that the lookup is fast. But that are you not using with your current solution.

So there is two ways what i can see. The one above or make sure that the keys are unique and get it by the lookup in the Dictionary. Like this:

Dictionary<string, Bitmap> lookup = new Dictionary<string, Bitmap>();
lookup.Add("A", new Bitmap(@"C:\08\letters\1\a1.bmp", true));
lookup.Add("B", new Bitmap(@"C:\08\letters\1\a2.bmp", true));
lookup.Add("C", new Bitmap(@"C:\08\letters\1\aa1.bmp", true));
lookup.Add("D", new Bitmap(@"C:\08\letters\1\b1.bmp", true));

Then you can get the Bitmap like this:

Bitmap bm;
if(lookup.TryGetValue("A",out bm))
{
    //Do something
}

Or if you know that the key is present in the Dictionary then you can do like this:

Bitmap bm;
bm= lookup["A"];



回答3:


First, it's different to have 'multiple bmp-s' to 'represent the key' - or have 'one key' associated (mapped) into multiple 'values' - which is what Yorye suggested rightly.
So, if you want more values attached to a single key - then you can use something like Dictionary<TKey, IList<TValue>> - where TKey and TValue are types you need.
But that doesnt' solve indexing and querying of the data.
That assumes that your 'key' is just 'A' in your case - which is not clear what it is.
So in that case you're using the 'dictionary' for something that it shouldn't be used. Dictionary is a hashing structure (basically indexes all its entries into buckets etc.) which servers the purpose of speeding up the querying process, locating the 'right' value.
As I see in your case the 'key' is/are the 'set of bitmaps' which sort of present a 'signature' of the OCR-ed image, if I"m right? I'm not much into the OCR but I'm guessing here.
That complicates things a bit, you'd need to create a 'composite' key of a sort.
The 'key' and not the 'value' (or value list) would be the bitmaps (providing they can be made to be comparable and equal or non-equal, also there's a problem of how you compare multiple values to multiple values etc.).
If that's the case usually (but for simpler cases than yours), you'd create a custom class and make that class have a GetHashCode() Equals override (or IEqualityComparer) etc. so that it can be used as a key in dictionaries. And then you use that as a key.
Again, in your case I think that's a bit of a stretch (in a sense that it's not easy to implement).
Basically you need to think about 'querying' the data, not much as storing. What are the real 'keys' for your system. If it's a bitmap, that's always the same (or if not how you compare to signature bmps) then you might save some bmp hashcode instead and use that as a key - and compare that, instead of bmps.
i.e. you need to think about things like that - and then the solution will usually be obvious, what you need to use.
I would not recommend a list, as that's a poor-men's choice - unless you might have only a couple so it's easy to go through it by hand, somehow I dont' think that's the case in your case.
If you need some way of 'indexing' by some key or keys - then it's usually the dictionary (or dictionary is involved in some way or part) - but you can have many 'dictionaries' - or combinations. Also you can have 'many types of keys' and values etc.
You'd need to give us some data for that.
hope this helps
EDIT: And lastly - getting the right 'hash-code' is also not a simple thing to do - as with your custom structure, comnparing, that's something you need to work out yourself - so that boils down to what's your key - and what represents the 'key' (as in which property, value best describes it and makes it unique, hard thing to do for an image/bmp?), the distribution of hash values etc.



来源:https://stackoverflow.com/questions/9963706/adding-multiple-bitmap-values-for-one-key-in-dictionary-with-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!