نوشتن یونیکد بر روی تصویر OpenCV - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

نوشتن یونیکد بر روی تصویر OpenCV

0 امتیاز
با تابع cv::Puttext خود کتابخانه opencv فقط میشه کاراکتر های اسکی را رسم کنیم من میخام یونیکد بر روی cv::Mat رسم کنم بوسیله Qt دوستان چی پیشنهاد میدن؟
سوال شده اردیبهشت 19, 1396  بوسیله ی خمیده (امتیاز 96)   9 17 25

1 پاسخ

0 امتیاز

برای اینکار می بایستی تصویر cv::Mat را به فرمت image کتابخانه Qt تبدیل کنید و سپس متن را با استفاده از متد drawText از کلاس QPainter بر روی image نوشته و در انتها QImage را به cv::Mat تبدیل کنید.

 

QImage mat2Image(const cv::Mat &mat, MatColorOrder order, QImage::Format formatHint)
{
    Q_ASSERT(mat.channels()==1 || mat.channels()==3 || mat.channels()==4);
    Q_ASSERT(mat.depth()==CV_8U || mat.depth()==CV_16U || mat.depth()==CV_32F);

    if (mat.empty())
        return QImage();

    //Adjust mat channels if needed, and find proper QImage format.
    QImage::Format format;
    cv::Mat mat_adjustCn;
    if (mat.channels() == 1) {
        format = formatHint;
        if (formatHint != QImage::Format_Indexed8
        #if QT_VERSION >= 0x050500
                && formatHint != QImage::Format_Alpha8
                && formatHint != QImage::Format_Grayscale8
        #endif
                ) {
            format = QImage::Format_Indexed8;
        }
    } else if (mat.channels() == 3) {
#if QT_VERSION >= 0x040400
        format = QImage::Format_RGB888;
        if (order == MCO_BGR)
            cv::cvtColor(mat, mat_adjustCn, CV_BGR2RGB);
#else
        format = QImage::Format_RGB32;
        cv::Mat mat_tmp;
        cv::cvtColor(mat, mat_tmp, order == MCO_BGR ? CV_BGR2BGRA : CV_RGB2BGRA);
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
        mat_adjustCn = mat_tmp;
#else
        mat_adjustCn = argb2bgra(mat_tmp);
#endif

#endif
    } else if (mat.channels() == 4) {
        //Find best format if the formatHint can not be applied.
        format = findClosestFormat(formatHint);
        if (format != QImage::Format_RGB32
                && format != QImage::Format_ARGB32
                && format != QImage::Format_ARGB32_Premultiplied
        #if QT_VERSION >= 0x050200
                && format != QImage::Format_RGBX8888
                && format != QImage::Format_RGBA8888
                && format != QImage::Format_RGBA8888_Premultiplied
        #endif
                ) {
#if QT_VERSION >= 0x050200
            format = order == MCO_RGBA ? QImage::Format_RGBA8888 : QImage::Format_ARGB32;
#else
            format = QImage::Format_ARGB32;
#endif
        }

        //Channel order requried by the target QImage
        MatColorOrder requiredOrder = getColorOrderOfRGB32Format();
#if QT_VERSION >= 0x050200
        if (formatHint == QImage::Format_RGBX8888
                || formatHint == QImage::Format_RGBA8888
                || formatHint == QImage::Format_RGBA8888_Premultiplied) {
            requiredOrder = MCO_RGBA;
        }
#endif

        if (order != requiredOrder)
            mat_adjustCn = adjustChannelsOrder(mat, order, requiredOrder);
    }

    if (mat_adjustCn.empty())
        mat_adjustCn = mat;

    //Adjust mat depth if needed.
    cv::Mat mat_adjustDepth = mat_adjustCn;
    if (mat.depth() != CV_8U)
        mat_adjustCn.convertTo(mat_adjustDepth, CV_8UC(mat_adjustCn.channels()), mat.depth() == CV_16U ? 1/255.0 : 255.0);

    //Should we convert the image to the format specified by formatHint?
    QImage image = mat2Image_shared(mat_adjustDepth, format);
    if (format == formatHint || formatHint == QImage::Format_Invalid)
        return image.copy();
    else
        return image.convertToFormat(formatHint);
}

cv::Mat image2Mat(const QImage &img, int requiredMatType, MatColorOrder requriedOrder)
{
    int targetDepth = CV_MAT_DEPTH(requiredMatType);
    int targetChannels = CV_MAT_CN(requiredMatType);
    Q_ASSERT(targetChannels==CV_CN_MAX || targetChannels==1 || targetChannels==3 || targetChannels==4);
    Q_ASSERT(targetDepth==CV_8U || targetDepth==CV_16U || targetDepth==CV_32F);

    if (img.isNull())
        return cv::Mat();

    //Find the closest image format that can be used in image2Mat_shared()
    QImage::Format format = findClosestFormat(img.format());
    QImage image = (format==img.format()) ? img : img.convertToFormat(format);

    MatColorOrder srcOrder;
    cv::Mat mat0 = image2Mat_shared(image, &srcOrder);

    //Adjust mat channells if needed.
    cv::Mat mat_adjustCn;
    const float maxAlpha = targetDepth==CV_8U ? 255 : (targetDepth==CV_16U ? 65535 : 1.0);
    if (targetChannels == CV_CN_MAX)
        targetChannels = mat0.channels();
    switch(targetChannels) {
    case 1:
        if (mat0.channels() == 3) {
            cv::cvtColor(mat0, mat_adjustCn, CV_RGB2GRAY);
        } else if (mat0.channels() == 4) {
            if (srcOrder == MCO_BGRA)
                cv::cvtColor(mat0, mat_adjustCn, CV_BGRA2GRAY);
            else if (srcOrder == MCO_RGBA)
                cv::cvtColor(mat0, mat_adjustCn, CV_RGBA2GRAY);
            else//MCO_ARGB
                cv::cvtColor(argb2bgra(mat0), mat_adjustCn, CV_BGRA2GRAY);
        }
        break;
    case 3:
        if (mat0.channels() == 1) {
            cv::cvtColor(mat0, mat_adjustCn, requriedOrder == MCO_BGR ? CV_GRAY2BGR : CV_GRAY2RGB);
        } else if (mat0.channels() == 3) {
            if (requriedOrder != srcOrder)
                cv::cvtColor(mat0, mat_adjustCn, CV_RGB2BGR);
        } else if (mat0.channels() == 4) {
            if (srcOrder == MCO_ARGB) {
                mat_adjustCn = cv::Mat(mat0.rows, mat0.cols, CV_MAKE_TYPE(mat0.type(), 3));
                int ARGB2RGB[] = {1,0, 2,1, 3,2};
                int ARGB2BGR[] = {1,2, 2,1, 3,0};
                cv::mixChannels(&mat0, 1, &mat_adjustCn, 1, requriedOrder == MCO_BGR ? ARGB2BGR : ARGB2RGB, 3);
            } else if (srcOrder == MCO_BGRA) {
                cv::cvtColor(mat0, mat_adjustCn, requriedOrder == MCO_BGR ? CV_BGRA2BGR : CV_BGRA2RGB);
            } else {//RGBA
                cv::cvtColor(mat0, mat_adjustCn, requriedOrder == MCO_BGR ? CV_RGBA2BGR : CV_RGBA2RGB);
            }
        }
        break;
    case 4:
        if (mat0.channels() == 1) {
            if (requriedOrder == MCO_ARGB) {
                cv::Mat alphaMat(mat0.rows, mat0.cols, CV_MAKE_TYPE(mat0.type(), 1), cv::Scalar(maxAlpha));
                mat_adjustCn = cv::Mat(mat0.rows, mat0.cols, CV_MAKE_TYPE(mat0.type(), 4));
                cv::Mat in[] = {alphaMat, mat0};
                int from_to[] = {0,0, 1,1, 1,2, 1,3};
                cv::mixChannels(in, 2, &mat_adjustCn, 1, from_to, 4);
            } else if (requriedOrder == MCO_RGBA) {
                cv::cvtColor(mat0, mat_adjustCn, CV_GRAY2RGBA);
            } else {//MCO_BGRA
                cv::cvtColor(mat0, mat_adjustCn, CV_GRAY2BGRA);
            }
        } else if (mat0.channels() == 3) {
            if (requriedOrder == MCO_ARGB) {
                cv::Mat alphaMat(mat0.rows, mat0.cols, CV_MAKE_TYPE(mat0.type(), 1), cv::Scalar(maxAlpha));
                mat_adjustCn = cv::Mat(mat0.rows, mat0.cols, CV_MAKE_TYPE(mat0.type(), 4));
                cv::Mat in[] = {alphaMat, mat0};
                int from_to[] = {0,0, 1,1, 2,2, 3,3};
                cv::mixChannels(in, 2, &mat_adjustCn, 1, from_to, 4);
            } else if (requriedOrder == MCO_RGBA) {
                cv::cvtColor(mat0, mat_adjustCn, CV_RGB2RGBA);
            } else {//MCO_BGRA
                cv::cvtColor(mat0, mat_adjustCn, CV_RGB2BGRA);
            }
        } else if (mat0.channels() == 4) {
            if (srcOrder != requriedOrder)
                mat_adjustCn = adjustChannelsOrder(mat0, srcOrder, requriedOrder);
        }
        break;
    default:
        break;
    }

    //Adjust depth if needed.
    if (targetDepth == CV_8U)
        return mat_adjustCn.empty() ? mat0.clone() : mat_adjustCn;

    if (mat_adjustCn.empty())
        mat_adjustCn = mat0;
    cv::Mat mat_adjustDepth;
    mat_adjustCn.convertTo(mat_adjustDepth, CV_MAKE_TYPE(targetDepth, mat_adjustCn.channels()), targetDepth == CV_16U ? 255.0 : 1/255.0);
    return mat_adjustDepth;
}


void drawUnicode(cv::Mat & img, const std::wstring& str, const cv::Rect& region, const cv::Scalar& color,
		const std::string& font_name, int font_size)
	{

		QPixmap pix;
		QImage image = mat2Image(img);
		QPainter p(&image);
		p.setPen(QPen(QColor(color.val[2], color.val[1], color.val[0])));
		QString fnt_name = QString::fromStdString(font_name);

		QFont font = p.font();
		font.setPointSize(font_size);
		font.setFamily(fnt_name);

		p.setFont(font);

		
		float factor = (float)region.width / p.fontMetrics().width(QString::fromStdWString(str));
		//if ((factor < 1) || (factor > 1.25))
		//{
		//	QFont f = p.font();
		//	f.setPointSizeF(f.pointSizeF()*factor);
		//	p.setFont(f);
		//}

		

		p.drawText(rect2QRectF(region), Qt::AlignCenter, QString::fromStdWString(str));

		img = image2Mat(image);

	}

 

پاسخ داده شده مهر 24, 1396 بوسیله ی مصطفی ساتکی (امتیاز 21,998)   24 34 75
...