mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Switch network camera to OpenCV
This commit is contained in:
parent
f4b1b64ae6
commit
6348976df7
|
@ -94,11 +94,6 @@ void Camera::unsuscribe()
|
|||
}
|
||||
}
|
||||
|
||||
QVideoFrame Camera::getLastVideoFrame()
|
||||
{
|
||||
return lastFrame;
|
||||
}
|
||||
|
||||
Mat Camera::getLastFrame()
|
||||
{
|
||||
Mat frame;
|
||||
|
@ -174,148 +169,67 @@ bool Camera::isFormatSupported(const QVideoSurfaceFormat& format) const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
QImage Camera::getLastImage()
|
||||
{
|
||||
if (!lastFrame.map(QAbstractVideoBuffer::ReadOnly))
|
||||
Mat3b src = getLastFrame();
|
||||
QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
|
||||
for (int y = 0; y < src.rows; ++y)
|
||||
{
|
||||
qWarning() << "Camera::getLastImage: Error maping last frame";
|
||||
return QImage();
|
||||
const cv::Vec3b *srcrow = src[y];
|
||||
QRgb *destrow = (QRgb*)dest.scanLine(y);
|
||||
for (int x = 0; x < src.cols; ++x)
|
||||
destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255);
|
||||
}
|
||||
int w = lastFrame.width(), h = lastFrame.height();
|
||||
int bpl = lastFrame.bytesPerLine(), cxbpl = bpl/2;
|
||||
QImage img(w, h, QImage::Format_RGB32);
|
||||
|
||||
if (frameFormat == QVideoFrame::Format_YUV420P)
|
||||
{
|
||||
uint8_t* yData = lastFrame.bits();
|
||||
uint8_t* uData = yData + (bpl * h);
|
||||
uint8_t* vData = uData + (bpl * h / 4);
|
||||
for (int i = 0; i< h; i++)
|
||||
{
|
||||
uint32_t* scanline = (uint32_t*)img.scanLine(i);
|
||||
for (int j=0; j < bpl; j++)
|
||||
{
|
||||
uint8_t Y = yData[i*bpl + j];
|
||||
uint8_t U = uData[i/2*cxbpl + j/2];
|
||||
uint8_t V = vData[i/2*cxbpl + j/2];
|
||||
|
||||
uint8_t R, G, B;
|
||||
fromYCbCrToRGB(Y, U, V, R, G, B);
|
||||
|
||||
scanline[j] = (0xFF<<24) + (R<<16) + (G<<8) + B;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (frameFormat == QVideoFrame::Format_YV12)
|
||||
{
|
||||
uint8_t* yData = lastFrame.bits();
|
||||
uint8_t* vData = yData + (bpl * h);
|
||||
uint8_t* uData = vData + (bpl * h / 4);
|
||||
for (int i = 0; i< h; i++)
|
||||
{
|
||||
uint32_t* scanline = (uint32_t*)img.scanLine(i);
|
||||
for (int j=0; j < bpl; j++)
|
||||
{
|
||||
uint8_t Y = yData[i*bpl + j];
|
||||
uint8_t U = uData[i/2*cxbpl + j/2];
|
||||
uint8_t V = vData[i/2*cxbpl + j/2];
|
||||
|
||||
uint8_t R, G, B;
|
||||
fromYCbCrToRGB(Y, U, V, R, G, B);
|
||||
|
||||
scanline[j] = (0xFF<<24) + (R<<16) + (G<<8) + B;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (frameFormat == QVideoFrame::Format_RGB32)
|
||||
{
|
||||
memcpy(img.bits(), lastFrame.bits(), bpl*h);
|
||||
}
|
||||
|
||||
lastFrame.unmap();
|
||||
return img;
|
||||
return dest;
|
||||
}
|
||||
|
||||
vpx_image Camera::getLastVPXImage()
|
||||
{
|
||||
Mat3b frame = getLastFrame();
|
||||
vpx_image img;
|
||||
img.w = img.h = 0;
|
||||
if (!lastFrame.isValid())
|
||||
return img;
|
||||
if (!lastFrame.map(QAbstractVideoBuffer::ReadOnly))
|
||||
{
|
||||
qWarning() << "Camera::getLastVPXImage: Error maping last frame";
|
||||
return img;
|
||||
}
|
||||
int w = lastFrame.width(), h = lastFrame.height();
|
||||
int bpl = lastFrame.bytesPerLine();
|
||||
int w = frame.size().width, h = frame.size().height;
|
||||
vpx_img_alloc(&img, VPX_IMG_FMT_I420, w, h, 1); // I420 == YUV420P, same as YV12 with U and V switched
|
||||
|
||||
if (frameFormat == QVideoFrame::Format_YUV420P)
|
||||
{
|
||||
uint8_t* yData = lastFrame.bits();
|
||||
uint8_t* uData = yData + (bpl * h);
|
||||
uint8_t* vData = uData + (bpl * h / 4);
|
||||
img.planes[VPX_PLANE_Y] = yData;
|
||||
img.planes[VPX_PLANE_U] = uData;
|
||||
img.planes[VPX_PLANE_V] = vData;
|
||||
}
|
||||
else if (frameFormat == QVideoFrame::Format_YV12)
|
||||
{
|
||||
uint8_t* yData = lastFrame.bits();
|
||||
uint8_t* uData = yData + (bpl * h);
|
||||
uint8_t* vData = uData + (bpl * h / 4);
|
||||
img.planes[VPX_PLANE_Y] = yData;
|
||||
img.planes[VPX_PLANE_U] = vData;
|
||||
img.planes[VPX_PLANE_V] = uData;
|
||||
}
|
||||
else if (frameFormat == QVideoFrame::Format_RGB32 || frameFormat == QVideoFrame::Format_ARGB32)
|
||||
{
|
||||
qWarning() << "Camera::getLastVPXImage: Using experimental RGB32 conversion code";
|
||||
uint8_t* rgb = lastFrame.bits();
|
||||
size_t i=0, j=0;
|
||||
qWarning() << "Camera::getLastVPXImage: Using experimental RGB32 conversion code" << w << ","<<h;
|
||||
size_t i=0, j=0;
|
||||
|
||||
for( int line = 0; line < h; ++line )
|
||||
for( int line = 0; line < h; ++line )
|
||||
{
|
||||
const cv::Vec3b *srcrow = frame[line];
|
||||
if( !(line % 2) )
|
||||
{
|
||||
if( !(line % 2) )
|
||||
for( int x = 0; x < w; x += 2 )
|
||||
{
|
||||
for( int x = 0; x < w; x += 2 )
|
||||
{
|
||||
uint8_t r = rgb[4 * i + 1];
|
||||
uint8_t g = rgb[4 * i + 2];
|
||||
uint8_t b = rgb[4 * i + 3];
|
||||
uint8_t r = srcrow[x][2];
|
||||
uint8_t g = srcrow[x][1];
|
||||
uint8_t b = srcrow[x][0];
|
||||
|
||||
img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16;
|
||||
img.planes[VPX_PLANE_U][j] = ((-38*r + -74*g + 112*b) >> 8) + 128;
|
||||
img.planes[VPX_PLANE_V][j] = ((112*r + -94*g + -18*b) >> 8) + 128;
|
||||
i++;
|
||||
j++;
|
||||
img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16;
|
||||
img.planes[VPX_PLANE_U][j] = ((-38*r + -74*g + 112*b) >> 8) + 128;
|
||||
img.planes[VPX_PLANE_V][j] = ((112*r + -94*g + -18*b) >> 8) + 128;
|
||||
i++;
|
||||
j++;
|
||||
|
||||
r = rgb[4 * i + 1];
|
||||
g = rgb[4 * i + 2];
|
||||
b = rgb[4 * i + 3];
|
||||
|
||||
img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16;
|
||||
i++;
|
||||
}
|
||||
r = srcrow[x+1][2];
|
||||
g = srcrow[x+1][1];
|
||||
b = srcrow[x+1][0];
|
||||
img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int x = 0; x < w; x += 1 )
|
||||
{
|
||||
for( int x = 0; x < w; x += 1 )
|
||||
{
|
||||
uint8_t r = rgb[4 * i + 1];
|
||||
uint8_t g = rgb[4 * i + 2];
|
||||
uint8_t b = rgb[4 * i + 3];
|
||||
uint8_t r = srcrow[x][2];
|
||||
uint8_t g = srcrow[x][1];
|
||||
uint8_t b = srcrow[x][0];
|
||||
|
||||
img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16;
|
||||
i++;
|
||||
}
|
||||
img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastFrame.unmap();
|
||||
return img;
|
||||
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ public:
|
|||
void suscribe(); ///< Call this once before trying to get frames
|
||||
void unsuscribe(); ///< Call this once when you don't need frames anymore
|
||||
cv::Mat getLastFrame(); ///< Get the last captured frame
|
||||
QVideoFrame getLastVideoFrame(); ///< Get the last captured frame
|
||||
QImage getLastImage(); ///< Convert the last frame to a QImage (can be expensive !)
|
||||
vpx_image getLastVPXImage(); ///< Convert the last frame to a vpx_image (can be expensive !)
|
||||
bool isFormatSupported(const QVideoSurfaceFormat & format) const;
|
||||
|
|
|
@ -62,22 +62,9 @@ void SelfCamView::showEvent(QShowEvent* event)
|
|||
event->accept();
|
||||
}
|
||||
|
||||
QImage Mat2QImage(const cv::Mat3b &src) {
|
||||
QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
|
||||
for (int y = 0; y < src.rows; ++y) {
|
||||
const cv::Vec3b *srcrow = src[y];
|
||||
QRgb *destrow = (QRgb*)dest.scanLine(y);
|
||||
for (int x = 0; x < src.cols; ++x) {
|
||||
destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255);
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
void SelfCamView::updateDisplay()
|
||||
{
|
||||
Mat frame = cam->getLastFrame();
|
||||
|
||||
displayLabel->setPixmap(QPixmap::fromImage(Mat2QImage(frame)));
|
||||
cam->getLastVPXImage();
|
||||
displayLabel->setPixmap(QPixmap::fromImage(cam->getLastImage()));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user