26#include "cvmatandqimage.h" 
   30#include "opencv2/core/core.hpp" 
   31#include "opencv2/imgproc/imgproc.hpp" 
   38cv::Mat argb2bgra(
const cv::Mat &mat)
 
   40    Q_ASSERT(mat.channels()==4);
 
   42    cv::Mat newMat(mat.rows, mat.cols, mat.type());
 
   43    int from_to[] = {0,3, 1,2, 2,1, 3,0};
 
   44    cv::mixChannels(&mat, 1, &newMat, 1, from_to, 4);
 
   48cv::Mat adjustChannelsOrder(
const cv::Mat &srcMat, MatColorOrder srcOrder, MatColorOrder targetOrder)
 
   50    Q_ASSERT(srcMat.channels()==4);
 
   52    if (srcOrder == targetOrder)
 
   53        return srcMat.clone();
 
   57    if ((srcOrder == MCO_ARGB && targetOrder == MCO_BGRA)
 
   58            ||(srcOrder == MCO_BGRA && targetOrder == MCO_ARGB)) {
 
   60        desMat = argb2bgra(srcMat);
 
   61    } 
else if (srcOrder == MCO_ARGB && targetOrder == MCO_RGBA) {
 
   63        desMat = cv::Mat(srcMat.rows, srcMat.cols, srcMat.type());
 
   64        int from_to[] = {0,3, 1,0, 2,1, 3,2};
 
   65        cv::mixChannels(&srcMat, 1, &desMat, 1, from_to, 4);
 
   66    } 
else if (srcOrder == MCO_RGBA && targetOrder == MCO_ARGB) {
 
   68        desMat = cv::Mat(srcMat.rows, srcMat.cols, srcMat.type());
 
   69        int from_to[] = {0,1, 1,2, 2,3, 3,0};
 
   70        cv::mixChannels(&srcMat, 1, &desMat, 1, from_to, 4);
 
   73        cv::cvtColor(srcMat, desMat, cv::COLOR_BGRA2RGBA);
 
   86#if QT_VERSION >= 0x040400 
   89#if QT_VERSION >= 0x050200 
   94#if QT_VERSION >= 0x050500 
  107#if QT_VERSION > 0x040400 
  127MatColorOrder getColorOrderOfRGB32Format()
 
  129#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN 
  140cv::Mat image2Mat(
const QImage &img, 
int requiredMatType, MatColorOrder requriedOrder)
 
  142    int targetDepth = CV_MAT_DEPTH(requiredMatType);
 
  143    int targetChannels = CV_MAT_CN(requiredMatType);
 
  144    Q_ASSERT(targetChannels==CV_CN_MAX || targetChannels==1 || targetChannels==3 || targetChannels==4);
 
  145    Q_ASSERT(targetDepth==CV_8U || targetDepth==CV_16U || targetDepth==CV_32F);
 
  154    MatColorOrder srcOrder;
 
  155    cv::Mat mat0 = image2Mat_shared(image, &srcOrder);
 
  158    cv::Mat mat_adjustCn;
 
  159    const float maxAlpha = targetDepth==CV_8U ? 255 : (targetDepth==CV_16U ? 65535 : 1.0);
 
  160    if (targetChannels == CV_CN_MAX)
 
  161        targetChannels = mat0.channels();
 
  162    switch(targetChannels) {
 
  164        if (mat0.channels() == 3) {
 
  165            cv::cvtColor(mat0, mat_adjustCn, cv::COLOR_RGB2GRAY);
 
  166        } 
else if (mat0.channels() == 4) {
 
  167            if (srcOrder == MCO_BGRA)
 
  168                cv::cvtColor(mat0, mat_adjustCn, cv::COLOR_BGRA2GRAY);
 
  169            else if (srcOrder == MCO_RGBA)
 
  170                cv::cvtColor(mat0, mat_adjustCn, cv::COLOR_RGBA2GRAY);
 
  172                cv::cvtColor(argb2bgra(mat0), mat_adjustCn, cv::COLOR_BGRA2GRAY);
 
  176        if (mat0.channels() == 1) {
 
  177            cv::cvtColor(mat0, mat_adjustCn, requriedOrder == MCO_BGR ? cv::COLOR_GRAY2BGR : cv::COLOR_GRAY2RGB);
 
  178        } 
else if (mat0.channels() == 3) {
 
  179            if (requriedOrder != srcOrder)
 
  180                cv::cvtColor(mat0, mat_adjustCn, cv::COLOR_RGB2BGR);
 
  181        } 
else if (mat0.channels() == 4) {
 
  182            if (srcOrder == MCO_ARGB) {
 
  183                mat_adjustCn = cv::Mat(mat0.rows, mat0.cols, CV_MAKE_TYPE(mat0.type(), 3));
 
  184                int ARGB2RGB[] = {1,0, 2,1, 3,2};
 
  185                int ARGB2BGR[] = {1,2, 2,1, 3,0};
 
  186                cv::mixChannels(&mat0, 1, &mat_adjustCn, 1, requriedOrder == MCO_BGR ? ARGB2BGR : ARGB2RGB, 3);
 
  187            } 
else if (srcOrder == MCO_BGRA) {
 
  188                cv::cvtColor(mat0, mat_adjustCn, requriedOrder == MCO_BGR ? cv::COLOR_BGRA2BGR : cv::COLOR_BGRA2RGB);
 
  190                cv::cvtColor(mat0, mat_adjustCn, requriedOrder == MCO_BGR ? cv::COLOR_RGBA2BGR : cv::COLOR_RGBA2RGB);
 
  195        if (mat0.channels() == 1) {
 
  196            if (requriedOrder == MCO_ARGB) {
 
  197                cv::Mat alphaMat(mat0.rows, mat0.cols, CV_MAKE_TYPE(mat0.type(), 1), cv::Scalar(maxAlpha));
 
  198                mat_adjustCn = cv::Mat(mat0.rows, mat0.cols, CV_MAKE_TYPE(mat0.type(), 4));
 
  199                cv::Mat in[] = {alphaMat, mat0};
 
  200                int from_to[] = {0,0, 1,1, 1,2, 1,3};
 
  201                cv::mixChannels(in, 2, &mat_adjustCn, 1, from_to, 4);
 
  202            } 
else if (requriedOrder == MCO_RGBA) {
 
  203                cv::cvtColor(mat0, mat_adjustCn, cv::COLOR_GRAY2RGBA);
 
  205                cv::cvtColor(mat0, mat_adjustCn, cv::COLOR_GRAY2BGRA);
 
  207        } 
else if (mat0.channels() == 3) {
 
  208            if (requriedOrder == MCO_ARGB) {
 
  209                cv::Mat alphaMat(mat0.rows, mat0.cols, CV_MAKE_TYPE(mat0.type(), 1), cv::Scalar(maxAlpha));
 
  210                mat_adjustCn = cv::Mat(mat0.rows, mat0.cols, CV_MAKE_TYPE(mat0.type(), 4));
 
  211                cv::Mat in[] = {alphaMat, mat0};
 
  212                int from_to[] = {0,0, 1,1, 2,2, 3,3};
 
  213                cv::mixChannels(in, 2, &mat_adjustCn, 1, from_to, 4);
 
  214            } 
else if (requriedOrder == MCO_RGBA) {
 
  215                cv::cvtColor(mat0, mat_adjustCn, cv::COLOR_RGB2RGBA);
 
  217                cv::cvtColor(mat0, mat_adjustCn, cv::COLOR_RGB2BGRA);
 
  219        } 
else if (mat0.channels() == 4) {
 
  220            if (srcOrder != requriedOrder)
 
  221                mat_adjustCn = adjustChannelsOrder(mat0, srcOrder, requriedOrder);
 
  229    if (targetDepth == CV_8U)
 
  230        return mat_adjustCn.empty() ? mat0.clone() : mat_adjustCn;
 
  232    if (mat_adjustCn.empty())
 
  234    cv::Mat mat_adjustDepth;
 
  235    mat_adjustCn.convertTo(mat_adjustDepth, CV_MAKE_TYPE(targetDepth, mat_adjustCn.channels()), targetDepth == CV_16U ? 255.0 : 1/255.0);
 
  236    return mat_adjustDepth;
 
  241QImage mat2Image(
const cv::Mat &mat, MatColorOrder order, 
QImage::Format formatHint)
 
  243    Q_ASSERT(mat.channels()==1 || mat.channels()==3 || mat.channels()==4);
 
  244    Q_ASSERT(mat.depth()==CV_8U || mat.depth()==CV_16U || mat.depth()==CV_32F);
 
  251    cv::Mat mat_adjustCn;
 
  252    if (mat.channels() == 1) {
 
  255        #
if QT_VERSION >= 0x050500
 
  262    } 
else if (mat.channels() == 3) {
 
  263#if QT_VERSION >= 0x040400 
  265        if (order == MCO_BGR)
 
  266            cv::cvtColor(mat, mat_adjustCn, cv::COLOR_BGR2RGB);
 
  270        cv::cvtColor(mat, mat_tmp, order == MCO_BGR ? CV_BGR2BGRA : CV_RGB2BGRA);
 
  271#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN 
  272        mat_adjustCn = mat_tmp;
 
  274        mat_adjustCn = argb2bgra(mat_tmp);
 
  278    } 
else if (mat.channels() == 4) {
 
  280        format = findClosestFormat(formatHint);
 
  284        #
if QT_VERSION >= 0x050200
 
  290#if QT_VERSION >= 0x050200 
  298        MatColorOrder requiredOrder = getColorOrderOfRGB32Format();
 
  299#if QT_VERSION >= 0x050200 
  303            requiredOrder = MCO_RGBA;
 
  307        if (order != requiredOrder)
 
  308            mat_adjustCn = adjustChannelsOrder(mat, order, requiredOrder);
 
  311    if (mat_adjustCn.empty())
 
  315    cv::Mat mat_adjustDepth = mat_adjustCn;
 
  316    if (mat.depth() != CV_8U)
 
  317        mat_adjustCn.convertTo(mat_adjustDepth, CV_8UC(mat_adjustCn.channels()), mat.depth() == CV_16U ? 1/255.0 : 255.0);
 
  320    QImage image = mat2Image_shared(mat_adjustDepth, format);
 
  329cv::Mat image2Mat_shared(
const QImage &img, MatColorOrder *order)
 
  337#if QT_VERSION >= 0x040400 
  347            *order = getColorOrderOfRGB32Format();
 
  349#if QT_VERSION >= 0x050200 
  357#if QT_VERSION >= 0x050500 
  370QImage mat2Image_shared(
const cv::Mat &mat, 
QImage::Format formatHint)
 
  372    Q_ASSERT(mat.type() == CV_8UC1 || mat.type() == CV_8UC3 || mat.type() == CV_8UC4);
 
  378    if (mat.type() == CV_8UC1) {
 
  380        #
if QT_VERSION >= 0x050500
 
  387#if QT_VERSION >= 0x040400 
  388    } 
else if (mat.type() == CV_8UC3) {
 
  391    } 
else if (mat.type() == CV_8UC4) {
 
  395        #
if QT_VERSION >= 0x050200
 
  405    QImage img(mat.data, mat.cols, mat.rows, mat.step, formatHint);
 
  409        QVector<QRgb> colorTable;
 
  410        for (
int i=0; i<256; ++i)
 
  411            colorTable.
append(qRgb(i,i,i));
 
qsizetype bytesPerLine() const const
 
QImage copy(const QRect &rectangle) const const
 
bool isNull() const const
 
void setColorTable(const QList< QRgb > &colors)
 
void append(QList< T > &&value)