转自:http://www.learnopencv.com/why-does-opencv-use-bgr-color-format/

One of the elements of good design is the principle of least astonishment ( a.k.a principle of least surprise). A good intuitive design makes the user not think.

When you see a handle on a door, you want to pull it. When you see a door with a metal plate, you want to push it. Those are the expectations of a user of the door and when the designer of a door respects these expectations, a user can use the door without exerting any mental energy. But if the design is inconsistent with a user’s expectation, a simple act of opening a door can become a mental burden.

OpenCV is a very useful library, but when it comes to the principle of least surprise, it is an unqualified disaster. When I am writing Computer Vision code in MATLAB, I rarely refer to the documentation. While working with OpenCV, I have the docs permanently open in a browser tab.

OpenCV seems to have been built with the principle of maximum surprise in mind! And it all begins with the default BGR pixel format. It does not play well with libraries that use the standard RGB pixel format. E.g. when you try to display an image using matplotlib after reading it using imread in OpenCV, the result looks funny.

“Why not use RGB when everybody else and their aunts use RGB?”

This is the question I asked Dr. Gary Bradski, founder of OpenCV, when I met him at a conference a few months back, although I left out the part about everybody and their aunts using RGB. He answered my question with another question.

“Why is the the US standard railroad gauge 4 feet, 8.5 inches?”

The answer to that question of course is “Because of Roman horse’s ass!”

For people who do not know this not-so-true story, I have copied the following from snopes

The US standard railroad gauge (width between the two rails) is 4 feet, 8.5 inches. That’s an exceedingly odd number. Why was that gauge used?

Because that’s the way they built them in England, and the US railroads were built by English expatriates.

Why did the English build them like that? Because the first rail lines were built by the same people who built the pre-railroad tramways, and that’s the gauge they used.

Why did “they” use that gauge then? Because the people who built the tramways used the same jigs and tools that they used for building wagons which used that wheel spacing.

Okay! Why did the wagons have that particular odd wheel spacing? Well, if they tried to use any other spacing, the wagon wheels would break on some of the old, long distance roads in England, because that’s the spacing of the wheel ruts.

So who built those old rutted roads? The first long distance roads in Europe (and England) were built by Imperial Rome for their legions. The roads have been used ever since. And the ruts in the roads? Roman war chariots first formed the initial ruts, which everyone else had to match for fear of destroying their wagon wheels. Since the chariots were made for (or by) Imperial Rome, they were all alike in the matter of wheel spacing.

The United States standard railroad gauge of 4 feet, 8.5 inches derives from the original specification for an Imperial Roman war chariot. Specifications and bureaucracies live forever. So the next time you are handed a specification and wonder what horse’s ass came up with it, you may be exactly right, because the Imperial Roman war chariots were made just wide enough to accommodate the back ends of two war horses. Thus, we have the answer to the original question.

Now the twist to the story . . .

There’s an interesting extension to the story about railroad gauges and horses’ behinds. When we see a Space Shuttle sitting on its launch pad, there are two big booster rockets attached to the sides of the main fuel tank. These are solid rocket boosters, or SRBs. The SRBs are made by Thiokol at their factory in Utah. The engineers who designed the SRBs might have preferred to make them a bit fatter, but the SRBs had to be shipped by train from the factory to the launch site. The railroad line from the factory had to run through a tunnel in the mountains. The SRBs had to fit through that tunnel. The tunnel is slightly wider than the railroad track, and the railroad track is about as wide as two horses’ behinds.

So, the major design feature of what is arguably the world’s most advanced transportation system was determined over two thousand years ago by the width of a Horse’s Ass!

Why did they choose BGR color space in OpenCV ?

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.

BGR was a choice made for historical reasons and now we have to live with it. In other words, BGR is the horse’s ass in OpenCV.

Subscribe

If you liked this article, please subscribe to our newsletter and receive a free
Computer Vision Resource
guide. In our newsletter we share OpenCV tutorials and examples written
in C++/Python, and Computer Vision and Machine Learning algorithms and
news.

Subscribe Now

Filed Under: Computer Vision Stories Tagged With: BGR

  • Quite funny. Thanks for the post.

  • autocyz

    Actually,I never thought about it. Thanks for your story !

  • chebhou

    funny and informative , thanks

  • Having
    worked at Thiokol, I can tell you that they tell the story about the
    size of the boosters regularly and with some serious gusto.

  • Pal Szasz

    Isn’t 0x00bbggrr actually RGB on little-endian machines?

  • leolodreamland

    i just wasted ten minutes of my life to not get any kind of answer…

  • bafu

    Interesting and useful information, thank you for sharing!

  • yalaudah

    Haha finally understood the mystery behind this seemingly arbitrary choice. Thanks for the post!

  • RockSteady

    What a waste of resources, every time you need to call cvtColor RGB2BGR to use imshow.

  • Govind Singh

    LOL

Why does OpenCV use BGR color format ?【转】的更多相关文章

  1. OpenCV使用BGR而非RGB格式

    日常开发和交流时,我们习惯将图片的颜色通道按照RGB(red, green, blue)进行排列.闲来无聊,在把玩卷积神经网络模型时发现OpenCV并没有按照这个顺序读入图片.好奇地搜索一下OpenC ...

  2. opencv颜色提取color filting

    # -*- coding: utf-8 -* import numpy as np import cv2 cap = cv2.VideoCapture(0) while True: _ , frame ...

  3. opencv-4-成像系统与Mat图像颜色空间

    opencv-4-成像系统与Mat图像颜色空间 opencvc++qtmat 目标 知道 opencv 处理图像数据的格式 介绍 mat 基础内容 知道 BGR 颜色 显示 颜色转换 BGR 到 灰度 ...

  4. WPF实现背景透明磨砂,并通过HandyControl组件实现弹出等待框

    前言:上一个版本的Winform需要改成WPF来做界面,第一次接触WPF,在转换过程中遇到的需求就是一个背景透明模糊,一个是类似于 加载中…… 这样的等待窗口,等后台执行完毕后再关掉.在Winform ...

  5. 快速 图片颜色转换迁移 Color Transfer Opencv + Python

      Super fast color transfer between images About a month ago, I spent a morning down at the beach, w ...

  6. 快速遍历OpenCV Mat图像数据的多种方法和性能分析 | opencv mat for loop

    本文首发于个人博客https://kezunlin.me/post/61d55ab4/,欢迎阅读! opencv mat for loop Series Part 1: compile opencv ...

  7. opencv Mat基础

    Mat Mat由两部分构成 matrix header pointer to the matrix containing the pixel values Mat is basically a cla ...

  8. 【OpenCV开发】imread和imwrite的类型以及第三个参数关于图片压缩质量等

    本片参考博客:http://blog.csdn.net/poem_qianmo/article/details/20537737 基于OpenCV3.0,与原博客有出入. 在OpenCV1.0时代,基 ...

  9. imread opencv

    ''' Mat cv::imread ( const String & filename, int flags = IMREAD_COLOR ) Python: retval = cv.imr ...

随机推荐

  1. 第206天:http协议终极详解---看这一篇就够了

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...

  2. ZOJ1827_The Game of 31

    这是一个比较经典的博弈题目,今年网赛好像是南京赛上有一个类似的题目. 这种题目是没有一定公式或者函数的,需要自己dp或者搜索解决. 题意为分别给你4张写有1,2,3,4,5,6的卡片共24张,每次轮流 ...

  3. ZOJ3084_S-Nim

    题目的意思是这样的,给定你若干堆石子,每次你可以从任一堆取出某些固定数量的石子,每次取完后必须保证没堆石子的数量不为0,谁无法操作了就算fail. 刚刚开始看题目的时候有点也没有思路,甚至连Sg函数也 ...

  4. Educational Codeforces Round 55 Div. 2 翻车记

    A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...

  5. 【BZOJ2763】飞行路线(最短路)

    [BZOJ2763]飞行路线(最短路) 题面 BZOJ Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标 ...

  6. 函数式编程(1)-高阶变成(2)-filter

    filter Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的时,filter()把传入的函数依次作用于每个元素,然 ...

  7. ROS中的CMakeLists.txt (转)

    在ROS的编程过程中,如果CMakeLists.txt如果写不好,编译就很难成功.如果看不懂CMakeLists.txt那么很多错误你也不知道时什么回事.所以深入了解它是很右必要的.现在我们就来看看它 ...

  8. AndroidStudio环境搭建

    简单记录一下AS的环境搭建过程,包括SVN的使用. 一.下载和安装JDK 地址:http://www.oracle.com/technetwork/java/javase/downloads/inde ...

  9. python---tornado补充(异步非阻塞)

    一:正常访问(同一线程中多个请求是同步阻塞状态) import tornado.ioloop import tornado.web import tornado.websocket import da ...

  10. 使用quartz.jar 、quartz-jobs.jar 实现定时任务 。实现 定时采集 接口数据

    前言 定时任务管理,在java中有很多种的方式 ,有java自带的注解方式@Scheduled  等 ,现在我要说的是一种也是使用比较广泛的一种quartz管理 使用此类 需要的加jar包有 quar ...