您的位置:首页 > 运维架构

opencv基本操作(五)

2016-11-25 16:04 211 查看
imencode
imdecode
图片的编码与解码



void valueChanged(int changeCount) {

        this->setAlgorithm([=](const QImage & arg)->QImage {
            if (changeCount<1) { return arg; }
            auto i=changeCount;

            try {

                QImage image=arg.copy();
                const auto imageData=const_cast<uchar*>(image.constBits());
                const auto lineStep=image.bytesPerLine();
                const auto imageHeight=image.height();
                const auto imageWidth3=image.width()*3;
                const auto lineEnd=imageData+imageHeight*lineStep;
                std::vector<std::uint8_t> buffer;

                const std::vector<int> par={
                    CV_IMWRITE_JPEG_QUALITY,77,
                };
                cv::Mat input(imageHeight,image.width(),CV_8UC3,
                    imageData,lineStep);

                /*opencv架构级错误,导致大量无用运算*/
                cv::cvtColor(input,input,cv::COLOR_RGB2BGR);

                /*参考:*/
                /*view-source:https://m13253.github.io/JPEGreen/*/

                auto clamp=[](const auto & x)->std::uint8_t {
                    return (x>=0)?(x<=255)?
                        std::uint8_t(x):std::uint8_t(255)
                        :std::uint8_t(0);
                };

                auto clampuv=[](const auto & x)->std::int8_t {
                    return (x>=-128)?(x<=127)?
                        std::int8_t(x):std::int8_t(127)
                        :std::int8_t(-128);
                };

                while ((--i)>=0) {

                    /*RGB 与 YUV 低精度转换*/
                    auto line=imageData;
                    for (; line<lineEnd; line+=lineStep) {
                        auto p=line; auto pend=p+imageWidth3;
                        for (; p<pend; p+=3) {

                            auto &b=p[0];
                            auto &g=p[1];
                            auto &r=p[2];

                            const auto y=clamp((77*r+150*g+29*b)>>8);
                            const auto u=clampuv(((-43*r-85*g+128*b)>>8)-1);
                            const auto v=clampuv(((128*r-107*g-21*b)>>8)-1);

                            r=clamp((65536*y+91881*v)>>16);
                            g=clamp((65536*y-22553*u-46802*v)>>16);
                            b=clamp((65536*y+116130*u)>>16);

                        }
                    }

                    /*opencv架构级别错误,导致大量无用运算,
                    尤其是save/load图片过程中,第三方库一般是按照rgb设计的,
                    于是opencv要先将bgr转rgb,浪费大量时间
                    可以自行查看opencv源代码验证*/
                    cv::imencode(".jpeg",input,buffer,par);
                    input=cv::imdecode(buffer,CV_LOAD_IMAGE_COLOR,&input);

                    assert(imageData==input.data);
                }

                /*opencv架构级错误,导致大量无用运算*/
                cv::cvtColor(input,input,cv::COLOR_RGB2BGR);

                return std::move(image);
            }
            catch (...) { CPLUSPLUS_EXCEPTION(false); }
            return arg;
        });

    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv3 qt5 opencv qt c++11