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)