Добрый день. Подскажите, как с помощью OpenCV можно создать скриншот нужной части экрана( предположим мы знаем точные координаты заранее) и сохранить полученный результат в переменную типа IplImage?
За ранее благодарю за помощь.
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <gdiplus.h>
using namespace std;
#pragma comment(lib, "GdiPlus.lib") /* наш многострадальный lib-файл */
using namespace Gdiplus; /* как хочешь, но мне не в кайф постоянно писать Gdiplus:: */
static const GUID png =
{ 0x557cf406, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e } };
int main()
{
Sleep(5000);
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
HDC scrdc, memdc;
HBITMAP membit;
// Получаем HDC рабочего стола
// Параметр HWND для рабочего стола всегда равен нулю.
scrdc = GetDC(0);
// Определяем разрешение экрана
int Height, Width;
Height = GetSystemMetrics(SM_CYSCREEN);
Width = GetSystemMetrics(SM_CXSCREEN);
// Создаем новый DC, идентичный десктоповскому и битмап размером с экран.
memdc = CreateCompatibleDC(scrdc);
membit = CreateCompatibleBitmap(scrdc, Width, Height);
// membit = CreateCompatibleBitmap(scrdc, 100, 100);
SelectObject(memdc, membit);
// Улыбаемся... Снято!
BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
// BitBlt(memdc, 0, 0, 100, 100, scrdc, 0, 0, SRCCOPY);
HBITMAP hBitmap;
hBitmap =(HBITMAP) SelectObject(memdc, membit);
Gdiplus::Bitmap bitmap(hBitmap, NULL);
bitmap.Save(L"D:\\screen11.jpg", &png);
DeleteObject(hBitmap);
//GdiplusShutdown(gdiplusToken);
return 0;
}
BITMAPINFO BMI;
//ZeroMemory( &BMI, sizeof BMI );
BMI.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
BMI.bmiHeader.biWidth = Width;
BMI.bmiHeader.biHeight = -Height;
BMI.bmiHeader.biPlanes = 1;
BMI.bmiHeader.biBitCount = 32;
BMI.bmiHeader.biCompression = BI_RGB;
cv::Mat image = cv::Mat(Height, Width, CV_8UC4);
GetDIBits( scrdc, hBitmap, 0, Height, image.data, &BMI, DIB_RGB_COLORS );
#include <cv.h>
#include <highgui.h>
#include <windows.h>
#include <stdio.h>
#include <iostream>
//#include <gdiplus.h>
using namespace std;
#include <gdiplus.h>
#pragma comment(lib, "GdiPlus.lib") /* наш многострадальный lib-файл */
using namespace Gdiplus; /* как хочешь, но мне не в кайф постоянно писать Gdiplus:: */
static const GUID png =
{ 0x557cf406, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e } };
int main()
{
//Sleep(5000);
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
HDC scrdc, memdc;
HBITMAP membit;
// Получаем HDC рабочего стола
// Параметр HWND для рабочего стола всегда равен нулю.
scrdc = GetDC(0);
// Определяем разрешение экрана
int Height, Width;
Height = GetSystemMetrics(SM_CYSCREEN);
Width = GetSystemMetrics(SM_CXSCREEN);
// Создаем новый DC, идентичный десктоповскому и битмап размером с экран.
memdc = CreateCompatibleDC(scrdc);
membit = CreateCompatibleBitmap(scrdc, Width, Height);
// membit = CreateCompatibleBitmap(scrdc, 100, 100);
SelectObject(memdc, membit);
// Улыбаемся... Снято!
BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
HBITMAP hBitmap;
hBitmap =(HBITMAP) SelectObject(memdc, membit);
//Gdiplus::Bitmap bitmap(hBitmap, NULL);
//bitmap.Save(L"screenshot_bitmap.jpg", &png);
//DeleteObject(hBitmap);
//GdiplusShutdown(gdiplusToken);
BITMAPINFO BMI;
//ZeroMemory( &BMI, sizeof BMI );
BMI.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
BMI.bmiHeader.biWidth = Width;
BMI.bmiHeader.biHeight = -Height;
BMI.bmiHeader.biPlanes = 1;
BMI.bmiHeader.biBitCount = 32;
BMI.bmiHeader.biCompression = BI_RGB;
cv::Mat image = cv::Mat(Height, Width, CV_8UC4);
GetDIBits( scrdc, hBitmap, 0, Height, image.data, &BMI, DIB_RGB_COLORS );
cv::imshow("screen", image);
cv::imwrite("screenshot_cv.jpg", image);
cv::waitKey(0);
// освобождаем ресурсы
DeleteObject(hBitmap);
DeleteDC(memdc);
DeleteObject(membit);
ReleaseDC(0, scrdc);
return 0;
}
#include <cv.h>
#include <highgui.h>
#include <windows.h>
#include <stdio.h>
#include <iostream>
cv::Mat get_screenshot()
{
HDC scrdc, memdc;
HBITMAP membit;
// Получаем HDC рабочего стола
// Параметр HWND для рабочего стола всегда равен нулю.
scrdc = GetDC(0);
// Определяем разрешение экрана
int Height, Width;
Height = GetSystemMetrics(SM_CYSCREEN);
Width = GetSystemMetrics(SM_CXSCREEN);
// Создаем новый DC, идентичный десктоповскому и битмап размером с экран.
memdc = CreateCompatibleDC(scrdc);
membit = CreateCompatibleBitmap(scrdc, Width, Height);
SelectObject(memdc, membit);
// Улыбаемся... Снято!
BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
HBITMAP hBitmap;
hBitmap =(HBITMAP) SelectObject(memdc, membit);
//Gdiplus::Bitmap bitmap(hBitmap, NULL);
//bitmap.Save(L"screenshot_bitmap.jpg", &png);
//DeleteObject(hBitmap);
//GdiplusShutdown(gdiplusToken);
BITMAPINFO BMI;
//ZeroMemory( &BMI, sizeof BMI );
BMI.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
BMI.bmiHeader.biWidth = Width;
BMI.bmiHeader.biHeight = -Height;
BMI.bmiHeader.biPlanes = 1;
BMI.bmiHeader.biBitCount = 32;
BMI.bmiHeader.biCompression = BI_RGB;
cv::Mat image = cv::Mat(Height, Width, CV_8UC4);
GetDIBits( scrdc, hBitmap, 0, Height, image.data, &BMI, DIB_RGB_COLORS );
// освобождаем ресурсы
DeleteObject(hBitmap);
DeleteDC(memdc);
DeleteObject(membit);
ReleaseDC(0, scrdc);
return image;
}
int main()
{
cv::Mat image;
while(true) {
image = get_screenshot();
cv::imshow("screen", image);
//cv::imwrite("screenshot_cv.jpg", image);
int key = cv::waitKey(33);
if(key == VK_ESCAPE) {
break;
}
}
return 0;
}
IplImage * GetIplImage(HBITMAP HBM)
{
BITMAP BM;
LPBITMAPINFO BIP;
HDC DC;
DWORD DataSize;
WORD BitCount;
GetObject(HBM, sizeof(BITMAP), (LPSTR)&BM);
BitCount = (WORD)BM.bmPlanes * BM.bmBitsPixel;
DataSize = ((BM.bmWidth*BitCount+31) & ~31)/8*BM.bmHeight;
BIP=(LPBITMAPINFO)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(BITMAPINFOHEADER));
BIP->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BIP->bmiHeader.biWidth = BM.bmWidth;
BIP->bmiHeader.biHeight = BM.bmHeight;
BIP->bmiHeader.biPlanes = 1;
BIP->bmiHeader.biBitCount = BitCount;
BIP->bmiHeader.biCompression = 0;
BIP->bmiHeader.biSizeImage = DataSize;
BIP->bmiHeader.biXPelsPerMeter = 0;
BIP->bmiHeader.biYPelsPerMeter = 0;
if (BitCount < 16)
BIP->bmiHeader.biClrUsed = (1<<BitCount);
BIP->bmiHeader.biClrImportant = 0;
DC = GetDC(0);
BYTE * bits; // массив для битов изображения
long imgsize, pixels; // Различные размерности для записи файла
pixels = BIP->bmiHeader.biWidth * BIP->bmiHeader.biHeight;
/* switch(BIP->bmiHeader.biBitCount)
{
case 4:
imgsize = pixels / 2;
break;
case 8:
imgsize = pixels;
break;
case 16:
imgsize = pixels * 2;
break;
case 24:
imgsize = pixels * 3;
break;
case 32:
imgsize = pixels * 4;
break;
default:
break;
}*/
imgsize = pixels * 4;
// выделяем память под биты изображения
bits = (unsigned char*)GlobalAlloc(GMEM_FIXED,imgsize);
//Заполняем массив битов изображения
int i = GetDIBits( DC, // дескриптор контекста устройства
HBM, // дескриптор изображения
0, // первая выбираемая линия для изображения назначения
BIP->bmiHeader.biHeight, // количество выбираемых линий
bits, // адрес массива битов изображения
(BITMAPINFO*)&BIP->bmiHeader,// адрес структуры с данными изображения
DIB_RGB_COLORS // RGB или индекс палитры
);
// заполняем данные по изображению
int nChannels = BM.bmBitsPixel == 1 ? 1 : BM.bmBitsPixel/8 ;
int depth = BM.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;
IplImage* img = cvCreateImageHeader(cvSize(BM.bmWidth, BM.bmHeight), depth, nChannels);
// выделяем память под биты
img->imageData = (char*) malloc( BM.bmHeight * BM.bmWidth* nChannels * sizeof(char));
// копируем биты
memcpy( img->imageData, (char*)(bits), BM.bmHeight * BM.bmWidth * nChannels);
// изображение получается перевернутым
IplImage * imgModified = cvCreateImage(cvSize(img->width,img->height),img->depth, 3);
cvCvtColor(img, imgModified, CV_BGRA2BGR); // в img используеются 4 канала, мне необходимо только три
IplImage * imgMirror = cvCreateImage(cvSize(img->width,img->height),img->depth, 3);
cvMirror(imgModified, imgMirror); // приводим в нормальный вид
// убираем мусор
cvReleaseImage(&imgModified);
free( img->imageData);
cvReleaseImage(&img);
ReleaseDC(0, DC);
GlobalFree((HGLOBAL)bits);
HeapFree(GetProcessHeap(),0,(LPVOID)BIP);
return (imgMirror);
}
IplImage * GetIplImage(HBITMAP HBM)
{
BITMAP BM;
LPBITMAPINFO BIP;
HDC DC;
DWORD DataSize;
WORD BitCount;
GetObject(HBM, sizeof(BITMAP), (LPSTR)&BM);
BitCount = (WORD)BM.bmPlanes * BM.bmBitsPixel;
DataSize = ((BM.bmWidth*BitCount+31) & ~31)/8*BM.bmHeight;
BIP=(LPBITMAPINFO)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(BITMAPINFOHEADER));
BIP->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BIP->bmiHeader.biWidth = BM.bmWidth;
BIP->bmiHeader.biHeight = BM.bmHeight;
BIP->bmiHeader.biPlanes = 1;
BIP->bmiHeader.biBitCount = BitCount;
BIP->bmiHeader.biCompression = 0;
BIP->bmiHeader.biSizeImage = DataSize;
BIP->bmiHeader.biXPelsPerMeter = 0;
BIP->bmiHeader.biYPelsPerMeter = 0;
if (BitCount < 16)
BIP->bmiHeader.biClrUsed = (1<<BitCount);
BIP->bmiHeader.biClrImportant = 0;
DC = GetDC(0);
BYTE * bits; // массив для битов изображения
long imgsize, pixels; // Различные размерности для записи файла
pixels = BIP->bmiHeader.biWidth * BIP->bmiHeader.biHeight;
/* switch(BIP->bmiHeader.biBitCount)
{
case 4:
imgsize = pixels / 2;
break;
case 8:
imgsize = pixels;
break;
case 16:
imgsize = pixels * 2;
break;
case 24:
imgsize = pixels * 3;
break;
case 32:
imgsize = pixels * 4;
break;
default:
break;
}*/
imgsize = pixels * 4;
// выделяем память под биты изображения
bits = (unsigned char*)GlobalAlloc(GMEM_FIXED,imgsize);
//Заполняем массив битов изображения
int i = GetDIBits( DC, // дескриптор контекста устройства
HBM, // дескриптор изображения
0, // первая выбираемая линия для изображения назначения
BIP->bmiHeader.biHeight, // количество выбираемых линий
bits, // адрес массива битов изображения
(BITMAPINFO*)&BIP->bmiHeader,// адрес структуры с данными изображения
DIB_RGB_COLORS // RGB или индекс палитры
);
// заполняем данные по изображению
int nChannels = BM.bmBitsPixel == 1 ? 1 : BM.bmBitsPixel/8 ;
int depth = BM.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;
IplImage* img = cvCreateImageHeader(cvSize(BM.bmWidth, BM.bmHeight), depth, nChannels);
// выделяем память под биты
img->imageData = (char*) malloc( BM.bmHeight * BM.bmWidth* nChannels * sizeof(char));
// копируем биты
memcpy( img->imageData, (char*)(bits), BM.bmHeight * BM.bmWidth * nChannels);
// изображение получается перевернутым
IplImage * imgModified = cvCreateImage(cvSize(img->width,img->height),img->depth, 3);
cvCvtColor(img, imgModified, CV_BGRA2BGR); // в img используеются 4 канала, мне необходимо только три
IplImage * imgMirror = cvCreateImage(cvSize(img->width,img->height),img->depth, 3);
cvMirror(imgModified, imgMirror); // приводим в нормальный вид
// убираем мусор
cvReleaseImage(&imgModified);
free( img->imageData);
cvReleaseImage(&img);
ReleaseDC(0, DC);
GlobalFree((HGLOBAL)bits);
HeapFree(GetProcessHeap(),0,(LPVOID)BIP);
return (imgMirror);
}
Вернуться в Компьютерное зрение
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5