opencv write into a file the pixel values of binary image - c++

I would like to ask question about on how to export/write all the pixel values into a txt file or other format that can be opened by notepad for example. Below the program.
Thanks, HB
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdio.h>
#include <stdlib.h>
#include<fstream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
IplImage *img = cvLoadImage("MyImg.png");
CvMat *mat = cvCreateMat(img->height,img->width,CV_32FC3 );
cvConvert( img, mat );
outFile.open("MyFile.txt");
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
/// Get the (i,j) pixel value
CvScalar scal = cvGet2D( mat,j,i);
printf( "(%.f,%.f,%.f)",scal.val[0], scal.val[1],scal.val[2] );
}
printf("\n");
}
waitKey(1);
return 0;
}

The class Mat of the new OpenCV C++ API is preferred over IplImage because it simplifies your code: read more about the class Mat. For more information about loading an image, you could read Load, Modify, and Save an Image.
In order to write a text file using C++, you could use the class ofstream
Here is the source code.
#include <opencv2/opencv.hpp>
using namespace cv;
#include <fstream>
using namespace std;
int main( int argc, char** argv )
{
Mat colorImage = imread("MyImg.png");
// First convert the image to grayscale.
Mat grayImage;
cvtColor(colorImage, grayImage, CV_RGB2GRAY);
// Then apply thresholding to make it binary.
Mat binaryImage(grayImage.size(), grayImage.type());
threshold(grayImage, binaryImage, 128, 255, CV_THRESH_BINARY);
// Open the file in write mode.
ofstream outputFile;
outputFile.open("MyFile.txt");
// Iterate through pixels.
for (int r = 0; r < binaryImage.rows; r++)
{
for (int c = 0; c < binaryImage.cols; c++)
{
int pixel = binaryImage.at<uchar>(r,c);
outputFile << pixel << '\t';
}
outputFile << endl;
}
// Close the file.
outputFile.close();
return 0;
}

Related

can we apply threshold to single component of color space model like RGB and LAB?

trying to apply the Otsu threshold to single component "L" of LAB color space. But I can not figure out, how to specify it in OpenCV syntactically.
C++ code splits the Lab image into the separate channels.
#include <iostream>
using namespace std;
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world340.lib")
int main(void)
{
Mat img = imread("star.png", 1);
if (img.empty())
{
cout << "Could not read image file." << endl;
return 1;
}
Mat Lab;
Mat Lab_channels[3];
cvtColor(img, Lab, COLOR_BGR2Lab);
split(Lab, Lab_channels);
threshold(Lab_channels[0], Lab_channels[0], 127, 255, THRESH_OTSU);
return 0;
}
This C++ code uses extract channel to get just the first channel (channel 0).
#include <iostream>
using namespace std;
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world340.lib")
int main(void)
{
Mat img = imread("star.png", 1);
if (img.empty())
{
cout << "Could not read image file." << endl;
return 1;
}
Mat Lab;
Mat Lab_channel_0;
cvtColor(img, Lab, COLOR_BGR2Lab);
extractChannel(Lab, Lab_channel_0, 0);
threshold(Lab_channel_0, Lab_channel_0, 127, 255, THRESH_OTSU);
return 0;
}
Try this.

Simple RGB to Gray program crashes

I am trying to make a simple conversion of an image from RGB to Grayscale with OpenCV. I am using dev-cp on windows, here is the code:
#include <cv.h>
#include <highgui.h>
using namespace cv;
int main( int argc, char** argv )
{
char* imageName = argv[1];
Mat image;
image = imread( imageName );
Mat gray_image;
cvtColor(image,gray_image,CV_RGB2GRAY);
}
When I execute it, seems it crashes on the cvtColor.
please try
#include <cv.h>
#include <highgui.h>
using namespace cv;
int main( int argc, char** argv )
{
if (argc < 2) return 0;
char* imageName = argv[1];
Mat image;
image = imread( imageName );
if(image.empty()) return 0;
Mat gray_image;
cvtColor(image,gray_image,CV_RGB2GRAY);
imshow("image",image);
cv::waitKey(0);
return 0;
}

opencv iplimage binarization

I have an IplImage and I want to binarize (without using cvThreshold function) it using this following code:
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
static IplImage* img ;
img = cvLoadImage ("c:\\Mytest.jpg");
for(int i=0;i<img->height;i++)
{
for(int j=0;j<img->width;j++)
{
if (img->imageData[i*img->widthStep+j]<=10)
((uchar *)img->imageData)[i*img->widthStep+j]=255;
else
((uchar *)img->imageData)[i*img->widthStep+j]=0;
}
}
cvShowImage("After",img);
waitKey(0);
};
but this code affected only part of the image, like this:
see, it's a breeze with c++:
Mat img = imread("c:\\Mytest.jpg", 0); // load grayscale
Mat thresh = ( im <= 10 ); // that's it already!
imshow("After",img);
waitKey(0);
also look at threshold()

c++ How to put the video sequence into a vector<Mat> in OpenCV?

I am a new learner in c++. I read a video and I want to save the image sequence of the video into a vector called vector frame. The following is my code, please help me correct it if someone could, thank you a lot!
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
VideoCapture capture("/home/P1030.MOV");
int totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT);
vector<Mat> frame;
namedWindow("Display", WINDOW_AUTOSIZE);
for(int i=0; i < totalFrameNumber; i++)
{
frame.push_back(Mat());
imshow("Display", frame);
}
return 0;
}
You can do it as follows, although it is not recommended to load whole video in the memory at a single time.
int main()
{
VideoCapture capture("/home/P1030.MOV");
int totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT);
Mat currentFrame;
vector<Mat> frames;
namedWindow("Display", WINDOW_AUTOSIZE);
for(int i=0; i < totalFrameNumber; i++)
{
capture>>currentFrame;
frames.push_back(currentFrame.clone());
imshow("Display", currentFrame);
waitKey(10);
}
return 0;
}

OpenCV Buffer Overflow

I've got myself in a pickle on this project I'm working on. My main objective is to stitch two webcam feeds together and do object detection on them - bounding boxes, etc...the standard stuff.
I can't rid myself of buffer overflows though - the somewhat simplified code below (for readability) compiles x64 and soon after I get a buffer overflow error and this in the console:
"OpenCV Error: Assertion Failed (contour.checkVector(2) >= 0 && (contour.depth() == CV_32F || CV_32S) in unknown function, file...."
If comment out all of the lines that have to do with contours (from findContours to drawBoundingBoxes in main) it compiles and runs fine until I hit the spacebar to stop the program, and then I get another buffer overflow error. I get the same errors when I compile x32 as well, for the record.
Any help? Relevant code/pseudo-code pasted below:
// **defines.h**
//Definitions for anything in all caps, like WIDTH, HEIGHT, ERODEIT, etc...
// **protos.h**
// All function prototypes, nothing else
// **detection.cpp**
/* This is the code that related to background subtraction operations*/
#include <opencv2/opencv.hpp>
#include <iostream>
#include "defines.h"
using namespace std;
using namespace cv;
void initBackgroundSubtractor(BackgroundSubtractorMOG2 &bSub)
{
bSub.set("detectShadows", 1);
}
Mat doBackgroundSubtract(BackgroundSubtractorMOG2 &bSub, Mat panorama)
{
Mat foreground;
bSub.operator()(panorama, foreground);
erode(foreground, foreground, Mat(), Point(-1, -1), ERODEIT, BORDER_DEFAULT);
dilate(foreground, foreground, Mat(), Point(-1, -1), DILATEIT, BORDER_DEFAULT);
return foreground;
}
// **contourOps.cpp**
/* Functions that operate on, filter, or relate to OpenCV contours vectors */
#include <opencv2/opencv.hpp>
#include <vector>
#include <fstream>
#include "defines.h"
using namespace std;
using namespace cv;
/* Returns the centroid of a contour */
Point getCentroid(vector<Point> contour)
{
Point centroid;
Moments m;
m = moments(contour, false);
centroid.x = int(m.m10/m.m00);
centroid.y = int(m.m01/m.m00);
return centroid;
}
/* Draws a rectangle around a contour */
void drawBoundingBoxes(vector<vector<Point>> contours, Mat &img)
{
vector<Rect> boundRect(contours.size());
for(unsigned int j = 0; j < contours.size(); j++)
{
boundRect[j] = boundingRect(contours[j]);
rectangle(img, boundRect[j], Scalar(153,0,76), 2, 8, 0);
}
}
/* Removes contours from a vector if they're smaller than the argument "area" */
void contourSizeTrim (vector<vector<Point>> &contours, int area)
{
vector<vector<Point>>::iterator i = contours.begin();
while(i != contours.end())
{
if(contourArea(*i, false) < area)
i = contours.erase(i);
else
i++;
}
}
/* Removes contours from a vector if they're X % smaller than largest contour in vector */
void contourRelSizeTrim(vector<vector<Point>> &contours, int percent)
{
double maxArea = 0.0;
for(unsigned int i=0; i<contours.size(); i++)
{
if (contourArea(contours[i], false) > maxArea)
maxArea = contourArea(contours[i], false);
}
vector<vector<Point>>::iterator j = contours.begin();
while(j != contours.end())
{
if (contourArea(*j, false) < (double)(percent/100.0)*maxArea)
j = contours.erase(j);
else
j++;
}
}
// **realtimestitch.cpp**
#include <opencv2/opencv.hpp>
#include <opencv2/stitching/stitcher.hpp>
#include <vector>
#include <iostream>
#include "defines.h"
using namespace std;
using namespace cv;
void initStitcher(VideoCapture &capture1, VideoCapture &capture2, Stitcher &stitch)
{
capture1.set(CV_CAP_PROP_FRAME_WIDTH, WIDTH);
capture1.set(CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);
capture2.set(CV_CAP_PROP_FRAME_WIDTH, WIDTH);
capture2.set(CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);
detail::OrbFeaturesFinder *featureFinder = new detail::OrbFeaturesFinder(Size(3,1), 1000, 1.5f, 4);
stitch.setFeaturesFinder (featureFinder);
}
void calcCamTransform(VideoCapture &capture1, VideoCapture &capture2, Stitcher &stitch)
{
int64 t;
Mat fr1, fr2, copy1, copy2;
vector<Mat> imgs;
capture1 >> fr1;
capture2 >> fr2;
fr1.copyTo(copy1);
fr2.copyTo(copy2);
imgs.push_back(copy1);
imgs.push_back(copy2);
stitch.estimateTransform(imgs);
}
Mat doStitch(VideoCapture &capture1, VideoCapture &capture2, Stitcher &stitch)
{
Mat fr1, fr2, copy1, copy2, panorama;
vector<Mat> imgs;
capture1 >> fr1;
capture2 >> fr2;
fr1.copyTo(copy1);
fr2.copyTo(copy2);
imgs.push_back(copy1);
imgs.push_back(copy2);
Stitcher::Status status = stitch.composePanorama(imgs, panorama);
if (status != Stitcher::OK)
cout << "Error Stitching: Code: " << int(status) << endl;
return panorama;
}
// **main.cpp**
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include "defines.h"
#include "protos.h"
using namespace cv;
int main()
{
bool doTransform = true, doSizeFilter = true, doRelSizeFilter = true;
Mat pano, fGround;
vector<vector<Point>> contours;
VideoCapture cap1(0);
VideoCapture cap2(1);
Stitcher stitcher = Stitcher::createDefault();
BackgroundSubtractorMOG2 bGround;
initStitcher(cap1, cap2, stitcher);
initBackgroundSubtractor(bGround);
while (true)
{
if (doTransform)
{
calcCamTransform(cap1, cap2, stitcher);
doTransform = !doTransform;
}
pano = doStitch(cap1, cap2, stitcher);
fGround = doBackgroundSubtract(bGround, pano);
findContours(fGround, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
if (doSizeFilter)
contourSizeTrim(contours, AREATHRESH);
if (doRelSizeFilter)
contourRelSizeTrim(contours, RELSIZEPERCENT);
drawBoundingBoxes(contours, pano);
imshow("Stitched Image", pano);
if(waitKey(1) >= 0)
break;
}
return 0;
}
This is a problem related to OpenCV and VS2012 - on VS2010, there are no problems, and the code runs perfectly!
My opinion about this is that the contour you are trying to do something with an empty vector of contours. Have you verified that? Try a
if (contours.empty()) continue; // or here you can display the image to see if it is empty or not
I had the same problem because I was trying to give an epty vector to cv::IsContourConvex(...) function (see here).