TLDNR: All the sync services fight to set the icon. If you want your specified image to be the icon, you have to unlink all services for that contact.
Long version:
I'll take a stab at this: It seems to be a race condition synchronizing with multiple services. (The phrase "seems to be" is important, since this is entirely my speculation based on observation of the phone's behavior.
Each service that links that service's image with the phone's contact icons (Facebook, Flickr, Google, etc.) will set the contact icon at the time of a sync regardless of other services that also link contact icons (because the services are unaware of each other, more on this later). This means that for a given contact, the icon shown will be the one set by whichever service most recently did a sync. If the Facebook app does a sync, the icon will be the image from FB. If Flickr does a sync two minutes later, the icon will be the image from that user's Flicr account (which means the FB icon was only up for two minutes).
Now here's the rub: What you're expecting to happen is the reverse of what's really going on. You expect that contacts for which you've not specified an icon will have whatever icon whichever service decides to set for it, but if you explicitly set an icon, it would override any service's icon sync (effectively disabling icon sync for that contact). However, when you use a photo to "set as contact icon" on your phone, it doesn't actually set it as the contact icon on your phone, it sets it as the contact icon for the Google sync service. Hence, if Google was the last service to sync your contacts, that's the icon that will show for a contact. As soon as another service does a sync, the contact icon gets overwritten.
The reason for this is because your phone doesn't actually have contacts. Your phone only knows what Google's sync service tells it, and the Google service isn't any more special than the other sync services--the information from all of them just gets aggregated in the display on your phone. In the case of two services having different phone numbers both marked as "Home," you get two phone numbers in that contact marked "Home." In the case of an icon, though, there can be only one, and instead of dealing with this situation elegantly (by, say, providing a way to have the services negotiate, or negotiate conflicts for them by setting a one service to be the boss, or even setting their own service to be the boss), Google decided to not deal with it at all; hence the race condition. *sigh*
If you absolutely want a certain image as a contact's icon, you have to eliminate this race condition by eliminating any competition (you can't have a race with only one competitor). You have to unlink the contact from all the services. (Of course, when you unlink it from everything, you really haven't--you've unlinked it from everything except Google, because you can't really unlink it from Google, because "it" only exists in Google. The fact that there's even an icon to do that is a full-on, pants-on-fire user interface lie.)