I hope this will grow into a useful resource for other people using OpenCV in C++.
Copy an image into a region of interest (ROI) of a larger image
…assuming the same image type:
imageSmall.copyTo(imageBigger(Rect(iTargetX, iTargetY, imageSmall.size().width, imageSmall.size().height)));
Copy a ROI from one image into a new image
…given an existing image and a Rect describing an ROI:
Mat imageCrop; imageSource(rectROI).copyTo(imageCrop);
Convert a Mat into an IplImage
…NOTE – this does not make a copy – it just creates a new header over the existing data – if the Mat or the IplImage are changed, the other will also change. To make a separate copy, do a imageMat.copyTo(dst) first.
Mat imageMat; IplImage *imageIplImage; imageMat = imload(...); imageIplImage = new IplImage(imageMat);
Convert an IplImage into a Mat
…NOTE – haven’t yet found out whether this makes a copy of the data, or just a new header.
Mat image; IplImage *imageIplImage; imageMat = Mat(imageIplImage); mageMat);
Decode a JPG which is already in memory
If the JPG is already loaded into memory, but not decoded (i.e. it’s just been byte-for-byte read from disk), it can be decoded as follows using imdecode. First it has to be loaded into a Matrix.
void *pImageData; // Set this to point to the 'file' in memory long lImageDataSize; // Number of bytes Mat imageDecoded = cv::imdecode(cv::Mat(1, lImageDataSize, CV_8UC1, pImageData), CV_LOAD_IMAGE_UNCHANGED);
Encode a Mat into a JPG (or other image format) to a memory buffer instead of file
Mat imageSourceImage; vectorvectorImageEncoded; void *pEncodedData; imencode(".jpg", imageSource, vectorImageEncoded); // To copy the data to a void * or similar... pEncodedData = malloc(sizeof(char) * vectorImageEncoded.size()); memcpy(pEncodedData, &vectorImageEncoded[0], vectorImageEncoded.size());
How to fill an image with a single colour
image.setTo(cv::Scalar(iBlue,iGreen,iRed));
How to resize an image
imageSource.resize(imageSource, imageDisplay, Size(DISPLAY_COLS, DISPLAY_ROWS), INTER_NEAREST);
How to access pixels in an image
Note – this is NOT the quickest way of accessing pixels, especially accessing *all* pixels, or whole rows at a time – in those cases, there are ‘pointer arithmetic’ methods which are a lot more efficient. However, for ‘random’ access, this is the *easiest* way.
This example shows code getting the Blue, Green and Red channels for pixels coord iX,iY, from an RGB image (order of colour planes is BGR).
iB = imageBGR.at<cv::Vec3b>(iY,iX)[0] = 0; iG = imageBGR.at<cv::Vec3b>(iY,iX)[1] = 0; iR = imageBGR.at<cv::Vec3b>(iY,iX)[2] = 0;
Pixels can be set in exactly the same way:
imageRGB.at<cv::Vec3b>(iY,iX)[0] = 255; // Sets Blue channel
…etc
How to create a matrix
Mat matImage; matImage.create(iRows, iCols, CV_32FC1);
or
matImage.create(imageOther.size(), CV_8UC1);
…etc
How to find contours
Mat matImage; // 1 byte int, e.g. CV_8UC1 vector<vector<cv::Point> > contour; vector<Vec4i> vectorHierarchy; findContours(matImage, contour, vectorHierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); // NOTE - matImage WILL BE MODIFIED