想了一天了,怀疑是 OpenCV 的错。请教 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Jackhuang

想了一天了,怀疑是 OpenCV 的错。请教

  •  
  •   Jackhuang Nov 17, 2015 3735 views
    This topic created in 3815 days ago, the information mentioned may be changed or developed.

    在做一个图像的转换,读入 jpg,将 rgb 转为 luv.

    import cv2
    import numpy as np
    im=np.array([[[0.78039217, 0.73333335, 0.73333335]]],dtype=float32)
    im_xyz=cv2.cvtColor(im,cv2.COLOR_RGB2XYZ) #这个结果好像正确 array([[[ 0.71641064, 0.74334133, 0.79932952]]], dtype=float32)
    im_luv=cv2.cvtColor(im,cv2.COLOR_RGB2LUV)#array([[[ 76.84296417, 6.9851861 , 1.50677502]]], dtype=float32) #我怀疑这个是错误的。

    但是我用 matlab 跑的结果是 89.0798 , 3.5388 , 0.7616
    而我自己按照官方文档?的公式的结果 L 也是 89.0 。我真的觉得是不是 OpenCV 这个函数写错了。

    求解啊, OpenCV 真是神坑, imread 默认读入是 BGR ,我晕。 CV_RGB2XYZ 早就改成了 COLOR_RGB2XYZ 官方文档都不改。我也是醉了,一天都在搞这个,烦死了。

    Supplement 1    Nov 18, 2015

    我开了一个帖子问,(opencv 论坛)[http://answers.opencv.org/question/76503/may-i-ask-why-i-get-the-wrong-answer-about-rgb2luv/?answer=76549#post-id-76549]
    源代码方面
    float L = splineInterpolate(Y*LabCbrtTabScale, LabCbrtTab, LAB_CBRT_TAB_SIZE);
    L = 116.f*L - 16.f;
    并没有 1/3 的处理啊。
    而 lab 有 1/3 ,但是结果也是不同的,真的比较迷惑。
    float X = R*C0 + G*C1 + B*C2;
    float Y = R*C3 + G*C4 + B*C5;
    float Z = R*C6 + G*C7 + B*C8;

    float FX = X > 0.008856f ? std::pow(X, _1_3) : (7.787f * X + _a); float FY = Y > 0.008856f ? std::pow(Y, _1_3) : (7.787f * Y + _a); float FZ = Z > 0.008856f ? std::pow(Z, _1_3) : (7.787f * Z + _a); float L = Y > 0.008856f ? (116.f * FY - 16.f) : (903.3f * Y); float a = 500.f * (FX - FY); float b = 200.f * (FY - FZ); 

    有人告诉我是因为 LabCbrtTab is a lookup table of nonlinear rising slope that consider the luminance of the white reference Yn. 不懂了难道不是 rgb/255 左乘以一个矩阵么。
    所以还是自己去实现是么,这样怎么让我放心的用 OpenCV QAQ,连官方的函数都不对的即视感。

    13 replies    2015-11-18 18:57:25 +08:00
    northisland
        1
    northisland  
       Nov 17, 2015 via iPhone
    RGB 是约定俗成的说法, opencv4 通道顺序一般是 bgra , 4 个 8 位。
    cv2 坑太大建议尽早往 numpy 上回头
    caomaocao
        2
    caomaocao  
       Nov 17, 2015
    一直是 BGR 啊,液晶显示器上排列也说 BGR 吧。 RGB 是习惯称法吧...
    northisland
        3
    northisland  
       Nov 17, 2015
    function luv = rgb2luv( rgb )

    % convert to XYZ

    XYZ = [0.4125, 0.3576, 0.1804; ...
    0.2125, 0.7154, 0.0721; ...
    0.0193, 0.1192, 0.9502];

    xyz = XYZ * rgb;

    % convert to Luv

    luv = xyz;

    Yn = 1;
    Lt = 0.008856;
    Un_prime = 0.19784977571475;
    Vn_prime = 0.46834507665248;
    L0 = xyz(2,:) / Yn;

    warning off MATLAB:divideByZero;
    cOnstant= xyz(1,:) + 15 * xyz(2,:) + 3 * xyz(3,:);
    u_prime = (constant ~= 0) .* ((4 * xyz(1,:)) ./ constant) + (cOnstant== 0) * 4.0;
    vprime = (constant ~= 0) .* ((9 * xyz(2,:)) ./ constant) + (cOnstant== 0) * 9.0/15.0;

    luv(1,:) = (L0 > Lt) .* (116.0 * (L0 .^ (1/3)) - 16.0) + (L0 <= Lt) .* (903.3 * L0);
    luv(2,:) = 13 * luv(1,:) .* (u_prime - Un_prime);
    luv(3,:) = 13 * luv(1,:) .* (v_prime - Vn_prime);

    % be rid of NaNs
    luv(find(isnan(luv))) = 0;


    =_____=
    irainy
        4
    irainy  
       Nov 17, 2015
    @northisland 如何往 numpy 上回头?
    Jackhuang
        5
    Jackhuang  
    OP
       Nov 17, 2015
    @northisland 所以还是自己搞矩阵运算是么? QAQ
    Jackhuang
        6
    Jackhuang  
    OP
       Nov 17, 2015
    @northisland 我就是用 matlab 的这段代码检验的,答案是 89 , cv2 的结果是 76.84 。所以回来自己写矩阵才是王道,是么?
    hardware
        7
    hardware  
       Nov 17, 2015
    opencv 都算神坑的话 ros 简直就是黑洞
    northisland
        8
    northisland  
       Nov 17, 2015 via iPhone
    色彩空间线性变换大概是
    (x,y,z)T=(R , G , B)T ( r , g , b ) T
    就是矩阵乘法

    然后 xyz 往 luv 上算
    northisland
        9
    northisland  
       Nov 17, 2015 via iPhone
    @Jackhuang 自己写起码不会错
    northisland
        10
    northisland  
       Nov 17, 2015 via iPhone
    还有,就是查你颜色是 0 ~ 1 还说 0 ~ 255
    ihciah
        11
    ihciah  
       Nov 18, 2015
    好像转 YUV 也有点问题,我当初是直接查公式然后手写
    area346
        12
    area346  
       Nov 18, 2015
    opencv 挺好用的啊~不过我都是用 c++...python 用的少
    Jackhuang
        13
    Jackhuang  
    OP
       Nov 18, 2015
    @area346 应该差不多。。因为我是 Python 的粉丝 QAQ 。
    About     Help     Advertise     Blog     API     FAQ     Solana     5477 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 43ms UTC 08:38 PVG 16:38 LAX 01:38 JFK 04:38
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86