6 ms·
Why OpenCV uses BGR color space (2015)
- CardenB 8y agoTL;DR because it used to be popular among camera engineers and other people who manipulated image data early on.
- netsharc 8y agoHe should've made a 10 minute youtube video with animations of horse's ass, etc just to reveal this in the last 15 seconds... "if you liked this video, please like, subscribe, share and hit that bell icon to bla bla bla!". All that writing for a one line explanation...
- deleted 8y ago[deleted]
- avian 8y agoThis begs the question: why was BGR popular among camera engineers while RGB seems to be common in software?
- smallstepforman 8y agoBig endian vs little endian hardware?
- olliej 8y agoThat’s my understanding - a lot of the low power devices were big endian as for whatever reason big endian and risc seemed heavily correlated for decades, similarly the early mainframes and whatnot were big endian which is why a lot of network protocols use big endian formats.
- ekun 8y agoI've noticed that decisions like this are sometimes made for the sake of being the opposite of something else and then the two coexist decades within neighboring realms to the frustration and bafflement of users.
- barrystaes 8y ago"decisions like this are sometimes made for the sake of being the opposite of something else and then the two coexist decades within neighboring realms to the frustration and bafflement of users" Oh, you mean a political two-party system?
- roel_v 8y agoThe article says "The reason the early developers at OpenCV chose BGR color format is that back then BGR color format was popular among camera manufacturers and software providers. E.g. in Windows, when specifying color value using COLORREF they use the BGR format 0x00bbggrr.". So it claims that both camera engineers and software used BGR. I'm not convinced though - the Win32 macro to create a COLORREF is RGB(r,g,b), and there are 3 macros to get the R, G and B components out of a COLORREF. Until today I've never realized that a COLORREF stores its components in BGR order, and I've done Win32 graphics programming for 20 years. I think it has more to do with that the 'original' graphics-oriented architectures (SGI workstations and such) were big endian (for no particular reason, probably, although people have come up with retrofact rationalizations probably), and everyone just used that. Some 'standards' don't need a reason, someone just needs to make a choice and everyone else should just stick with it...
- Asooka 8y agoAlso, I'm pretty sure that COLORREF is xBGR format because colour data in memory is RGBx format and when you read it DWORD at a time on a little-endian machine, you end up with xBGR in registers. So an array of COLORREFs in memory is RGBx format... On the other hand, BMP is BGR format on disk and in memory[1] when using 24-bit colour. I think "opencv used BGR because BGR was the format of the default image file type on the first platform it was written for" might explain it better. Camera makers probably did the same thing - output BMPs before JPEG was developed. [1] Yes, technically BMP also has bitmasks that let you store the colour channels in any order with any precision, but almost all BMPs I've come across just use the default BGR format.
- liuliu 8y agoBefore deep learning is a thing, most computer vision tasks are done either in greyscale, or in a more reasonable colorspace (HSL, YUV etc.). Thus, you most likely just call cvCvtColor the first thing when extracted the frame, and it doesn't matter BGR or RGB. Only with deep learning, people start to use RGB directly, and this becomes something more interesting.
- h4b4n3r0 8y agoFor DL the colorspace is irrelevant as long as it's consistent between training and inference. I.e. if you train your model in RGB, it better be receiving RGB and not something else from the video feed or input images. Interestingly, models can also be trained in YUV (including its downsampled variants like YUYV), which can make them a tiny bit more efficient, both because there's less data, and because most camera chips can output YUV raw data directly. The net will learn whatever transform it needs to learn to make sense of the data.
- taeric 8y agoI don't think you can fully claim it is irrelevant. Especially not and point out that it can make things a bit more efficient. I think it is safe to say that the most important part is to be consistent between what you train on and what you infer against. However, it could be that one of the color spaces is more amenable to training. To my knowledge, that has not been completely ruled out. Indeed, it seems supported by your claim that they can get a tiny bit more efficient with some spaces. That said, this post is my long winded way of asking if you have links on that. :)
- h4b4n3r0 8y agoWhat makes YUYV more efficient is downsampling. You represent 2 pixels with 4 bytes instead of 6 due to the loss of spatial color information. If there's no downsampling, and there exists a transform between RGB and a given color space, your network will simply learn slightly differently. Remember that after the very first layer there's no notion of color space anymore.
- kalenx 8y agoWell, not only it is quite long just to say "BGR was used a lot back then", even the back story is wrong : https://www.snopes.com/fact-check/horses-pass/ https://www.snopes.com/fact-check/horses-pass/
- girvo 8y agoThe article said that as well, so I’m unsure what your complaint is.
- kalenx 8y agoNo, the post about OpenCV and BGR talks (for about 80% of it's length) about how everything we know in transportation, up to space shuttle, is linked to horse width. Which, as pointed out in the link I provided, is simply false (or at the very least a gross oversimplification).
- yreg 8y agoThe author stated that the story is "not-so-true" and copied from Snopes, but he didn't include the debunking.
- ballenf 8y agoOne of the key points of the "debunking" seems to itself make a logical error: > The eventual standardization of railroad gauge in the U.S. was due far less to a slavish devotion to a gauge inherited from England than to the simple fact that the North won the Civil War and, in the process, rebuilt much of the Southern railway system to match its own But the article earlier states that the North won the Civil War because of the logistical superiority of its rail lines that had settled on using the English standard gauge. Even if the South had settled on a single alternative gauge, they would have been unable to easily acquire rail equipment from abroad without added expense. Snopes' attempt at debunking achieves the opposite in my reading.
- deleted 8y ago[deleted]
- barrystaes 8y agoNever mind the horses arse! Its 4 feet, 8.5 inches because Human's thumbs and foots! chuckle (=1.4351 meters)
- cesarb 8y ago> E.g. in Windows, when specifying color value using COLORREF they use the BGR format 0x00bbggrr. Wait a little bit... isn't Windows little-endian [1]? Following the link in that sentence: > typedef DWORD COLORREF; > The low-order byte contains a value for the relative intensity of red; the second byte contains a value for green; and the third byte contains a value for blue. Given that Windows is and has always been little-endian, the byte order of a COLORREF is red first, then green, then blue, that is, the order is RGB. So the reason for BGR can't be Windows' COLORREF. [1] "A decision was made VERY long ago that Windows would not be ported to a big-endian processor." https://blogs.msdn.microsoft.com/larryosterman/2005/06/07/the-endian-of-windows/ https://blogs.msdn.microsoft.com/larryosterman/2005/06/07/th...
- kosma 8y agoThat's precisely how little endian works: first memory location is LSB. union { uint32_t l; uint8_t b[4]; } u = { .b = { 0x12, 0x34, 0x56, 0x78 } }; assert(u.l == 0x78563412);
- deleted 8y ago[deleted]
- mark-r 8y agoI thought for a moment that they had the order of COLORREF wrong, but I just double-checked the definitions of the GetRValue, GetGValue, and GetBValue macros. You are correct, writing that DWORD into memory would put them in RGB order not BGR.
- phkahler 8y agoSo because of legacy and unwillingness to change.
- jcranmer 8y agoSomewhat off-topic, but I just hate that Snopes article. It's wrong, and rather off-base. Functionally speaking, the main disconnect in the article is the difference between loading gauge and track gauge. 1435mm, or 8'4.5", may be the standard track gauge and uniform between most countries, but the actual standard loading gauges varies quite dramatically between different countries. The UK has a positively tiny loading gauge (about 2.5m), while the "standard" EU loading gauge is 3.1m, the US is slightly wider at 3.2m, and Sweden opts for a roomy 3.4m. The original notion that the SRB has to be "slightly" larger than the 1435mm track gauge is ridiculous, since as you can see, the loading gauge is over twice the width the track itself. Of course, there's also rooms to play tricks here if you need to. Schnabel cars can laterally offset the loads they're carrying by up to a meter or so, which gives you some extra height to play with if you're dealing with a double-track tunnel with an arched roof. The other point to mention that's completely omitted is there is a rather big difference between rail carriages and horse-drawn carriages. On rail carriages, the cars sit above the wheels, while horse-drawn carriages sit between the wheels. Something like this: bbbbbb bbbbbbbbbbbbbbbnbb b b b b w b b w w b b w w bbbbbb w w b b w waaaaaaaaw waaaaaaaaaw w w w w w w w w (Note that this is one of the reasons that the standard gauge was chosen over a broader gauge). As for why standard gauge was chosen, well, keep in mind that a) there was a lot of variance of track gauge in the 1800s, and b) the actual tolerance of track gauge was pretty damn massive. A track gauge differing by as much as two inches or so wouldn't have impeded the ability to transfer rolling stock. Stephenson built the first practical steam locomotive on a line that was 4'8", and so people who wanted to reuse his locomotives would have been drawn to a gauge around 4'8"-4'9". Gauges around 5" and slightly larger were selected in part to prevent interconnect between different railroads (basically, the same concept as vendor lockin). Contrary to the Snopes article, the South mostly standardized on 5' gauge, but it didn't have as dense a network as the North did. The South eventually converted to 4'9" gauge (the Pennsylvania Railroad's gauge)--in 1886, 20 years after the Civil War. Conversion thence to 4'8.5" took much longer, but was much less dramatic because 4'9" and 4'8.5" are within gauge tolerance.
- faragon 8y agoMay be the "Roman horse" here is that BGR is RGB in little endian format. Also, it has lots of advantages: little endian pixel handling allows using similar code for 24 and 32bpp (rr.gg.bb.rr.gg.bb vs rr.gg.bb.xx.rr.gg.bb.xx), so you can loop over pixes with offset += pixel size.
- childintime 8y agoThe article makes it sound as if moving OpenCV to RGB is as difficult as moving the US to the ISO metric system. Neither is impossible. If Europe manages to abolish national currencies, the US surely can abolish imperial units (and drive faster ;). But I guess that will only happen once under pressure of chinese overlords. I'm sure the day will come, so why wait?