OpenCV drawing Farneback optical flow in ROI. - c++

I've written a code to create bounding boxes and draw the Farneback optical flow inside. The optical flow is calculated normally before hand and then it is drawn separately for each ROI box.
The problem comes when I draw the flow. The flow comes out looking normal, but shifted down and right. Here's the output, notice the bottom right has the flow of the moving person.
Here is the frame with the flow drawn everywhere, showing where the flow should be drawn.
The code attached is stripped down for simplicity, so excuse me if there are a few undeclared Matrices or something.
#include ...
using namespace cv;
using namespace std;
Mat currentImage, img, printr, gray ,prevgray, flow;
void getRectanglesandROI(Mat &Mask, Mat &imgTmp, Mat &imgOut, vector<Rect> &outBoxes);
void DrawFlowMap(Mat Image, Mat ROI, Rect Box, Point centre);
int main (int argc, char *argv[]) {
VideoCapture inVid("input.avi");
if (!inVid.isOpened()) {
cout << "Failed to open the input video" << endl;
exit(5);}
int loop=0, count =0, MaxTargets=0;
bool test=true;
namedWindow("Detected");
int ex = inVid.get(CV_CAP_PROP_FOURCC);
double fps = inVid.get(CV_CAP_PROP_FPS);
int wait=1000/fps;
Size S = Size( (int) inVid.get(CV_CAP_PROP_FRAME_WIDTH), (int) inVid.get(CV_CAP_PROP_FRAME_HEIGHT));
int fr =inVid.get(CV_CAP_PROP_FRAME_COUNT);
VideoWriter output; // Open the output
output.open("output.avi", ex, fps, S, true);
if (!output.isOpened())
{
cout << "Could not open the output video for write: " << endl;
return -1;
}
//=============4EVR=================
while(test){
inVid>>currentImage;
if (currentImage.empty())
{
count++;
//if (count==1){if (waitKey(0)==27){waitKey(2);}}
if (count==1){fs.release(); break;}
cout <<"Max Targets=" <<MaxTargets<< endl<< "End of video, looping" << endl<<endl;
inVid.set(CV_CAP_PROP_POS_AVI_RATIO, 0);
loop=0;
}
cvtColor(currentImage, gray,CV_RGB2GRAY);
if (prevgray.empty()){gray.copyTo(prevgray);}
currentImage.copyTo(img);
calcOpticalFlowFarneback(prevgray,gray,flow,0.5,3,21,20,5,1.2,0);
vector<Rect> outputBoxes;
getRectanglesandROI(fgMaskMOG2, img, currentImage, outputBoxes);
gray.copyTo(prevgray);
imshow("Detected", currentImage);
waitKey(wait);
}
return 0;
}
//============END===========================================================
void getRectanglesandROI(Mat &Mask, Mat &imgTmp, Mat &imgOut, vector<Rect> &outBoxes){
vector<vector<Point> > v;
vector<int> targets;
int tarArea=1;
findContours(Mask, v, CV_RETR_EXTERNAL/*CV_RETR_LIST*/, CV_CHAIN_APPROX_SIMPLE);
for (int j = 0; j < v.size(); j++) {
if (tarArea < v[j].size()) { // excluding tiny contours
targets.push_back(j);
}
}
for (int j = 0; j < targets.size(); j++) {
drawContours(imgTmp, v, targets[j], Scalar(255, 0, 255), 1, 8);
Rect rect = boundingRect(v[targets[j]]);
roi=currentImage(rect);
DrawFlowMap(currentImage, roi, rect);
}
}
void DrawFlowMap(Mat Image, Mat ROI, Rect Box){
Point pt1 = Point(Box.x, Box.y);
for( int y=0; y<roi.rows; y+=5){ //this is the issue area, probably.
for (int x=0;x<roi.cols;x+=5){
const Point2f& flowatxy=flow.at<Point2f>(y,x);
line(Image, Point(cvRound(pt1.x+x), cvRound(pt1.y+y)),
Point(cvRound(pt1.x+x+flowatxy.x), cvRound(pt1.y+y+flowatxy.y)), Scalar(0,255,0)); ///FLOW LINES
}
}
}

Easy peasy, after looking at the images for a while (crying) I noticed that it was drawing the flow in the right places, but the flowatxy in that place was wrong. So I changed the flowatxy declaration to the following:
const Point2f& flowatxy=flow.at<Point2f>( pt1.y+y , pt1.x+x );

Related

OpenCV(Version 3.2.0) - Extraction of ROI

I have been working on extracting the ROI from the image given below.
Fluroscopic Image
This code is supposed to work for images of all resolutions.
My approach is to:
Find the largest contour and store it's ID.
Use minEnclosingCircle() function to find the minimum bounding circle.
But, this circle is being offset to the top-left corner.
Here is my code:
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int largestContourId(vector<vector<Point>> contourVec); //Function to find ID of largest contour
int main(int argc, char **argv )
{
if ((argv[1] != 0) && (argv[2] != 0))
{
String path = argv[1]; //Path of image to be given here
Mat img = imread(path); // Initialize and read image
Mat img_copy = img.clone(); //Make a copy of the orignal image
Mat img_gray; //Initialize grey image matrix
Mat thresh; //Initialize threshold mask
Mat result; //Initialize resulting image matrix
int maxAreaContourId; //This stores ID of the largest contour
Point2f center; //MEC center
float radius; //MEC radius
vector<vector<Point>> contours; // Defining contour vector
vector<Vec4i> hierarchy; //Defining contour hierarchy vector
cout << "Resolution of image: " << img.size() << endl;
cvtColor(img,img_gray,COLOR_BGR2GRAY); // Convert from colored to grayscale image
threshold(img_gray,thresh,5,255,THRESH_BINARY); //Apply threshold mask and convert to a binary image
imshow("Binary img",thresh); //Display binary image in B&W
findContours(thresh,contours,hierarchy,RETR_TREE,CHAIN_APPROX_NONE); //Find contours and hierarchy within using the Simple Approximation method
maxAreaContourId = largestContourId(contours); //Store largest contour ID
minEnclosingCircle(contours[maxAreaContourId],center,radius);
circle(img_copy,center,radius-20.0,Scalar(255,255,255),-1);
bitwise_not(img_copy,img_copy);
bitwise_xor(img,img_copy,result);
imshow("Orignal Image",img); //Show orignal image
imshow("Result",result); //Show the result of the plot
waitKey(0); //Wait for input
imwrite(argv[2],result); //Write the result to a file
destroyAllWindows();
return 0;
}
else
{
cout << "Please enter CLA in the format: *input_file* *output_file*" << endl;
return 0;
}
}
int largestContourId(vector<vector<Point>> contourVec) //Function to find ID of largest contour
{
double maxArea = 0; //Intialize area contour
int maxAreaContourId = -1; //Intialize largest contour ID
for(int j = 0; j < contourVec.size(); j++) //Cycle through contour vector
{
double newArea = contourArea(contourVec.at(j)); //Variable for comparing area
if (newArea > maxArea) //Comparison of areas
{
maxArea = newArea;
maxAreaContourId = j;
}
}
return maxAreaContourId; //Largest contour ID to be returned
}
This is my output:
Output Fluroscopic Image
I would like this code to work for all sorts of images even if the text is written on th e ROI itself.
Please let me know if my current approach is feasible or not.
Suggestions are always welcome.

OpenCV: can't get segmentation of image using k-means

Before going into deep of my question, I want you to know that I've read other posts on this forum, but none regards my problem.
In particular, the post here answers the question "how to do this?" with k-means, while I already know that I have to use it and I'd like to know why my implementation doesn't work.
I want to use k-means algorithm to divide pixels of an input image into clusters, according to their color. Then, after completing such task, I want each pixel to have the color of the center of the cluster it's been assigned to.
Taking as reference the OpenCV examples and other stuff retrieved on the web, I've designed the following code:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
Mat src = imread( argv[1], 1 );
// reshape matrix
Mat resized(src.rows*src.cols, 3, CV_8U);
int row_counter = 0;
for(int i = 0; i<src.rows; i++)
{
for(int j = 0; j<src.cols; j++)
{
Vec3b channels = src.at<Vec3b>(i,j);
resized.at<char>(row_counter,0) = channels(0);
resized.at<char>(row_counter,1) = channels(1);
resized.at<char>(row_counter,2) = channels(2);
row_counter++;
}
}
//cout << src << endl;
// change data type
resized.convertTo(resized, CV_32F);
// determine termination criteria and number of clusters
TermCriteria criteria(TermCriteria::COUNT + TermCriteria::EPS, 10, 1.0);
int K = 8;
// apply k-means
Mat labels, centers;
double compactness = kmeans(resized, K, labels, criteria, 10, KMEANS_RANDOM_CENTERS, centers);
// change data type in centers
centers.convertTo(centers, CV_8U);
// create output matrix
Mat result = Mat::zeros(src.rows, src.cols, CV_8UC3);
row_counter = 0;
int matrix_row_counter = 0;
while(row_counter < result.rows)
{
for(int z = 0; z<result.cols; z++)
{
int index = labels.at<char>(row_counter+z, 0);
//cout << index << endl;
Vec3b center_channels(centers.at<char>(index,0),centers.at<char>(index,1), centers.at<char>(index,2));
result.at<Vec3b>(matrix_row_counter, z) = center_channels;
}
row_counter += result.cols;
matrix_row_counter++;
}
cout << "Labels " << labels.rows << " " << labels.cols << endl;
//cvtColor( src, gray, CV_BGR2GRAY );
//gray.convertTo(gray, CV_32F);
imshow("Result", result);
waitKey(0);
return 0;
}
Anyway, at the end of computation, I simply get a black image.
Do you know why?
Strangely, if I initialize result matrix as
Mat result(src.size(), src.type())
at the end of algorithm it will display exactly the input image, without any segmentation.
In particular, I have two doubts:
1) is it correct to lay the RGB values of a pixel on each row of matrix resized the way I've done it? is there a way to do it without a loop?
2) what's exactly the content of centers, after k-means function finishes working? it's a 3 columns matrix, does it contains the RGB values of clusters' centers?
thanks for support.
-The below posted OpenCV program assigns the user preferred color to a particular pixel value in an image
-ScanImageAndReduceC() is a predefined method in OpenCV to scan through all the pixels of an Image
-I.atuchar>(10, 10) = 255; is used to access a particular pixel value of an image
Here is the code:
Mat& ScanImageAndReduceC(Mat& I)
{
// accept only char type matrices
CV_Assert(I.depth() == CV_8U);
int channels = I.channels();
int nRows = I.rows;
int nCols = I.cols * channels;
if (I.isContinuous())
{
nCols *= nRows;
nRows = 1;
}
int i, j;
uchar* p;
for (i = 0; i < nRows; ++i)
{
p = I.ptr<uchar>(i);
for (j = 0; j < nCols; ++j)
{
I.at<uchar>(10, 10) = 255;
}
}
return I;
}
-------Main Program-------
Calling the above method in our main program
diff = ScanImageAndReduceC(diff);
namedWindow("Difference", WINDOW_AUTOSIZE);// Create a window for display.
imshow("Difference", diff); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}

OpenCV2 findContours(), contours size not equals to hierarchy size

I tried to use findContour() to get contours from following picture
The code is like this:
Mat mat = imread("123.jpg");
cv::imshow("123.jpg",mat);
Mat hsv;
cvtColor(mat,hsv,COLOR_BGR2HSV);
Mat dst;
inRange(hsv,Scalar(0,0,49),Scalar(47,165,111),dst);
cout<<"dst channels:"<<dst.channels()<<endl;
int c0=0,c255=0,other=0;
for(int i=0;i<dst.rows;i++){
for(int j=0;j<dst.cols;j++){
int v = dst.at<uchar>(i,j);
if(v == 0){
c0++;
}else if(v == 255){
c255++;
}else{
other++;
}
}
}
cout<<"0 count:"<<c0<<",255 count:"<<c255<<",other value count:"<<other<<endl;
cv::erode(dst,dst,cv::Mat(),cv::Point(1,1),6);
cv::dilate(dst,dst,cv::Mat(),cv::Point(1,1),6);
cv::medianBlur(dst,dst,15);
cv::imshow("inRange",dst);
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
Mat temp;
dst.copyTo(temp);
findContours(temp,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE );
cout<<"contours size:"<<contours.size()<<endl;
cout<<"hierarchy size:"<<hierarchy.size()<<endl;
for (int index = 0; index >= 0; index = hierarchy[index][0]) {
cout<<"hierarchy at:"<<index<<","<<hierarchy[index]<<endl;
cv::drawContours(mat,contours,index,Scalar(120,255,0));
}
cv::imshow("contours",mat);
waitKey(0);
return 0;
the binary image is like this:
the final contour image is like this:
The log printed in console window is like this:
I don't know why contours size is smaller than hierarchy size. in fact, there should be three "EXTERNAL" shapes. seems missed one shape in output contours. this issue trapped me for a day and i'm going to be crazy now...anybody knows why there are only two elements in contours ?did i do something wrong?
This works as expected for me:
contours size:3
hierarchy size:3
hierarchy at:0,[1, -1, -1, -1]
hierarchy at:1,[2, 0, -1, -1]
hierarchy at:2,[-1, 1, -1, -1]
Possible problems in your code are:
dst may be incorrectly initialized
dst may not be binary, i.e. can have values different from 0 and 255
Code:
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
// Load image
Mat3b img = imread("path_to_image");
// Convert to grayscale
Mat1b bin;
cvtColor(img, bin, COLOR_BGR2GRAY);
// Binarize (remove jpeg artifacts)
bin = bin > 100;
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(bin.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
cout << "contours size:" << contours.size() << endl;
cout << "hierarchy size:" << hierarchy.size() << endl;
for (int index = 0; index >= 0; index = hierarchy[index][0]) {
cout << "hierarchy at:" << index << "," << hierarchy[index] << endl;
cv::drawContours(img, contours, index, Scalar(120, 255, 0), 2);
}
imshow("Result", img);
waitKey();
return 0;
}
My VS tool was linked to ..\opencv\build\x64\vc12\lib and I was experiencing similar issues.
I solved this by changing the link to ..\opencv\build\x86\vc12\lib
I'm using Visual Studio 2010 on Windows 7.

Distance between same point in two different images not consistent - OpenCV/C++

So I have two Thermal images (Potato quality I know but it is what I have to work with), the first two images in this album. I am using some code from a tutorial that is super common but have edited a lot of it.
http://imgur.com/a/Zch7C
So what I am doing in my code is
1. Detecting KeyPoints
2. Describe the KeyPoints
3. Match the KeyPoints
4. Keep only good points
5. Gather both Query and Train points
6. Find Homography
7. Warp one of the images
8. Repeat the above steps for the warped image and the other original image
Now my question is: Should the change in the (x,y) distance between two of the same points on the two different images be the same for every set of points?
The whole frame is moving in the same direction so no matter what matching points we look at the change should be the same should it not?
What I am finding is that the points all different in the distance, some are 5 pixels different and some are 700 pixels, the only thing I can think is happening is that the match is not actually good and it is comparing two points that are no where near the same point in the separate frames.
I need to know what the offset is so that I can overlay one frame on top of the other then average out the pixel values that are overlapping and build a new images from the composite/average of the two originals.
My code I am using is below:
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "stitch.cpp"
#include "opencv2\stitching\stitcher.hpp"
#include "opencv2\nonfree\features2d.hpp"
using namespace cv;
void readme();
Mat describe(Mat img, vector<KeyPoint> key);
vector<KeyPoint> detect(Mat img);
vector<DMatch> match(Mat descriptionOne, Mat descriptionTwo);
/** #function main */
int main(int argc, char** argv)
{
VideoCapture cap("vid.mp4");
vector<Mat> Vimg;
cout << "Grabbing Images" << endl;
for (int i = 0; i < 2; i++)
{
cout << "Grabbing Frame" << i << endl;
Mat temp;
cap.read(temp);
Vimg.push_back(temp);
imwrite("image" + to_string(i) + ".jpg", temp);
for (int j = 0; j < 80; j++)
cap.grab();
}
//Mat cimg1 = Vimg[0];
//Mat cimg2 = Vimg[1];
Mat cimg1 = imread("cap1.png");
Mat cimg2 = imread("cap2.png");
cout << "Starting Stitching" << endl;
//Converting the original images to grayscale
Mat img1, img2;
cvtColor(cimg1, img1, CV_BGR2GRAY);
cvtColor(cimg2, img2, CV_BGR2GRAY);
//Detecting Keypoints for original two images
vector<KeyPoint> keypointOne = detect(img1), keypointTwo = detect(img2);
Mat mkeypointOne, mkeypointTwo;
drawKeypoints(cimg1, keypointOne, mkeypointOne, Scalar(0, 0, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
drawKeypoints(cimg2, keypointTwo, mkeypointTwo, Scalar(0, 0, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imwrite("keypointOne.jpg", mkeypointOne);
imwrite("keypointTwo.jpg", mkeypointTwo);
//Computing descriptors
Mat descriptionOne = describe(img1, keypointOne), descriptionTwo = describe(img2, keypointTwo);
//Matching descriptors
vector<DMatch> matches = match(descriptionOne, descriptionTwo);
double max = 0;
double min = 100;
//Calculation of max and min distances
for (int i = 0; i < matches.size(); i++)
{
double dist = matches[i].distance;
if (dist < min) min = dist;
if (dist > max) max = dist;
}
vector<DMatch> goodMatches;
//Keep only good matches
for (int i = 0; i < matches.size(); i++)
{
if (matches[i].distance < 2*min)
goodMatches.push_back(matches[i]);
}
//Localize
vector<Point2f> obj;
vector<Point2f> scene;
for (int i = 0; i < goodMatches.size(); i++)
{
obj.push_back(keypointOne[goodMatches[i].queryIdx].pt);
scene.push_back(keypointTwo[goodMatches[i].trainIdx].pt);
}
/*
for (int k = 0; k < obj.size(); k++)
{
cout << "Point data for Match #" << k << endl;
cout << "\tImage 1 Point: " << obj[k] << endl;
cout << "\tImage 2 Point: " << scene[k] << endl;
}*/
Mat H = findHomography(obj, scene, CV_RANSAC);
//Warping the image to fit on first image
Mat cwarpImage, warpImage;
//TODO: figure out the right size for this image that is created
warpPerspective(cimg2, cwarpImage, H, Size(img2.cols + img1.cols, img2.rows + img1.rows));
/*
Mat result;
Mat half(warpImage, Rect(0, 0, img2.cols, img2.rows));
cimg2.copyTo(half);
*/
imwrite("warp.jpg", warpImage);
//Processing Image
cvtColor(cwarpImage, warpImage, CV_BGR2GRAY);
vector<KeyPoint> keypointWarp = detect(warpImage);
Mat descriptionWarp = describe(warpImage, keypointWarp);
vector<DMatch> warpMatches = match(descriptionOne, descriptionWarp);
Mat mkeypointWarp;
drawKeypoints(cwarpImage, keypointWarp, mkeypointWarp, Scalar(0, 0, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imwrite("keypointWarp.jpg", mkeypointWarp);
Mat match;
drawMatches(cimg1, keypointOne, warpImage, keypointWarp, warpMatches, match, Scalar(0, 0, 255), Scalar(255, 0, 0), vector<char>(), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
//imshow("match", match);
imwrite("matches.jpg", match);
//Localize
vector<Point2f> obj2;
vector<Point2f> scene2;
for (int i = 0; i < warpMatches.size(); i++)
{
obj2.push_back(keypointOne[warpMatches[i].queryIdx].pt);
scene2.push_back(keypointWarp[warpMatches[i].trainIdx].pt);
}
for (int k = 0; k < obj.size(); k++)
{
cout << "Point data for Match #" << k << endl;
cout << "\tImage 1 Point: " << obj2[k] << endl;
cout << "\tImage 2 Point: " << scene2[k] << endl;
}
vector<unsigned char> inliersMask;
Mat H2 = findHomography(obj, scene, CV_RANSAC, 3, inliersMask);
vector<DMatch> inliers;
for (size_t i = 0; i < inliersMask.size(); i++)
{
if (inliersMask[i])
inliers.push_back(warpMatches[i]);
}
warpMatches.swap(inliers);
Mat match2;
drawMatches(cimg1, keypointOne, warpImage, keypointWarp, warpMatches, match2, Scalar(0, 0, 255), Scalar(255, 0, 0), vector<char>(), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imwrite("homorgraphyOutlierMatch.jpg", match2);
cout << "Writing Warp Image" << endl;
imwrite("warpimage.jpg", warpImage);
cout << H << endl;
waitKey(0);
}
Mat describe(Mat img, vector<KeyPoint> key)
{
Mat temp;
SurfDescriptorExtractor extractor;
extractor.compute(img, key, temp);
return temp;
}
vector<KeyPoint> detect(Mat img)
{
vector<KeyPoint> temp;
SurfFeatureDetector detector(400);
detector.detect(img, temp);
return temp;
}
vector<DMatch> match(Mat descriptionOne, Mat descriptionTwo)
{
vector<DMatch> temp;
BFMatcher matcher(NORM_L2, true);
matcher.match(descriptionOne, descriptionTwo, temp);
return temp;
}
EDIT:
I set Cross Check to true in the BFMatcher and implemented Homography outlier detection from Mastering_OpenCV. Here are the two new results. I was not sure if I was supposed to implement both cross check and KnnMatch so I only did cross check.
http://imgur.com/a/1P7Xt
As you can see they are a lot better but there are still some there that should not be there. I ran it with both full color and thermal images.
New code is above as well.
While the change in distance between point correspondences won't be the same for all points in the general case, you wouldn't expect to have deltas of the order of 700 pixels with an image size of 1300ish.
by inspection of the images you've posted, it's clear that you have point correspondences which are not correct (simply, you have lots of crossed lines in your matches between images)
This suggests that your step 4 isn't doing a great job. You might want to try setting the second parameter of your Brute Force matcher to true to enable cross-check test:
BFMatcher matcher(NORM_L2, true);
You might also want to consider the ratio test for outlier removal as described here How to apply Ratio Test in order to remove outliers in a multiple object detection matcher?

Creating bigger image out of small image Mat [opencv, background subtraction]

I have an image i1. I am supposed to create another Mat m1 of size (image.rows*3, image.cols*3).
In m1, I'm supposed to fill the pixel value in the following way. (Please do see the image):
Here is my code-
#include <highgui.h>
#include "opencv2/opencv.hpp"
#include <fstream>
using namespace cv;
static Mat NeurMap1, NeurMap2, NeurMap3, frame, hsv_Frame;
std::ofstream myfile;
void InitializeNeurMap(cv::Mat Channel[3])
{
int i=0,j=0,m_i=0,m_j=0, t1=0, t2=0;
for(i=0; i < frame.rows; i++)
{
for(j=0;j < frame.cols;j++)
{
t1= i*n+1; t2 = j*n+1;
for(m_i=t1-1; m_i <= t1+1;m_i++)
{
for(m_j=t2-1; m_j <= t2+1; m_j++)
{
NeurMap1.at<uchar>(m_i, m_j)= frame.at<uchar>(i,j);
}
}
}
}
std::cout<<m_j;
myfile<<frame;
}
int main()
{
myfile.open("NeurMaptext.txt");
String filename="BootStrap/b%05d.bmp";// sequence of frames are read
VideoCapture cap(filename);
if(!cap.isOpened()) // check if we succeeded
return -1;
namedWindow("edges",1);
//namedWindow("frames",1);
Mat Channel[3];
cap>>frame;
NeurMap1 = Mat::zeros(frame.rows*n, frame.cols*n, frame.type());
InitializeNeurMap(Channel);
imshow("edges",NeurMap1);waitKey(33);
for(;;)
{
cap>>frame;
if(frame.empty())
break;
}
system("pause");
return 0;
}
The input image is RGB[160*120]. Why am I not getting the columns in the output image given in the link above?.
You can simply call resize() by passing the INTER_NEAREST parameter, i.e. using the nearest-neighbor interpolation.
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
unsigned char data[] = { 1, 2, 3, 4, 5, 6 };
Mat img(2, 3, CV_8UC1, data);
cout << img << endl;
Mat res(6, 9, CV_8UC1);
resize(img, res, res.size(), 0, 0, INTER_NEAREST);
cout << res << endl;
return 0;
}
You will get:
In you are getting three only one-third of image filled because, probably you are passing 3 channel(colour) image to the function and treat it as a single channel image. So change the above code to,
void InitializeNeurMap(cv::Mat Channel[3])
{
for(int i=0; i < frame.rows; i++){
for(int j=0;j < frame.cols;j++){
for(int k=0;k<n;k++){
for(int l=0;l<n;l++){
NeurMap1.at<Vec3b>(i*n+k,j*n+l)[0] = frame.at<Vec3b>(i,j)[0]; //Access Blue channel
NeurMap1.at<Vec3b>(i*n+k,j*n+l)[1] = frame.at<Vec3b>(i,j)[1];//Access green channel
NeurMap1.at<Vec3b>(i*n+k,j*n+l)[2] = frame.at<Vec3b>(i,j)[2]; //Access red channel
}
}
}
}
myfile<<frame;
}
See the reult