I want to capture an image and use it as a gray level image.
I have the following code:
CvCapture *p = cvCreateCameraCapture(0);
cvSetCaptureProperty(p, CV_CAP_PROP_FRAME_WIDTH, 1024);
cvSetCaptureProperty(p, CV_CAP_PROP_FRAME_HEIGHT, 1024);
IplImage* frame;
for (int i = 0; i < 25; i++)
{
frame = cvQueryFrame(p);
}
cvSaveImage("test.jpg", frame);
Mat r = imread("test.jpg", 1);
Mat inputImage;
cvtColor(r, inputImage, COLOR_RGB2GRAY);
In my code frame is an RGB image (three dimensions). when I read the saved image with r it has two channels.
I have two questions:
why this happens?
how can I have one dimensional image which is gray level?
For your first question: You should check which camera/hardware you are using? Also, confirm if frame has 2 channels by running:
cout << img->nChannels << endl;
For second part:
To read image as gray channel, change:
Mat r = imread("test.jpg", 1);
to
Mat r = imread("test.jpg", 0);
See this: docs
Related
I set my mask from BGR2HSV. I have my image:
How I can change the white color in the mask? So I want to change the white parts with other colors.
Mat mask;
mask = imread("C:\\Users\\...\\Desktop\\...\\mask.png");
if (!img.data)
{
cout << "Could not find the image";
return -1;
}
cvtColor(mask, mask, COLOR_BGR2HSV);
cvtColor(mask, mask, COLOR_HSV2BGR);
imshow("Ergebnis", mask);
waitKey(0);
Between two cvtColor functions, you need to split the image into its 3 channels with split. Looking at the conversion between RGB and HSV, make S channel 0 and choose an H value between [0-180]. Then, merge the channels back.
cv::Mat hsv = mask.clone(); // from your code
std::vector<cv::Mat> hsv_vec;
cv::split(hsv, hsv_vec);
cv::Mat &H = hsv_vec[0];
cv::Mat &S = hsv_vec[1];
cv::Mat &V = hsv_vec[2];
S = 0;
mask = (V > 10); // non-zero pixels in the original image
H(mask) = your_H_value_here; // H is between 0-180 in OpenCV
cv::merge(hsv_vec, hsv);
mask = hsv; // according to your code
As a side note, I suggest using convenient names for variables.
Good Day! I'm using imwrite command to save the image below after cropping them in OpenCV (C++) but it seems like it included the black portion surrounding it in writing. All I want is to save the cropped one. Please help.
Here's my code
Mat mask,draft,res;
int nPixels;
char c=0;
while(true && c!='q') {
imshow("SAMPLE", img);
if(!roi.isSet())
roi.set("SAMPLE");
if (roi.isSet()) {
roi.createMask(img.size());
mask = roi.getMask();
res = mask & img.clone();
imwrite("masked.png",res);
imshow("draft", res);
}
c = waitKey(1);
}
Here is an example how to crop an image and save the croped image (see comment from api55). Maybe that helps you.
cv::Mat img = cv::imread("Path/To/Image/image.png", cv::IMREAD_GRAYSCALE);
if(image.empty())
return -1;
cv::Rect roi(0, 0, 100, 100); // define roi here as x0, y0, width, height
cv::Mat cropedImg(img, roi);
cv::imwrite("Path/To/Save/Location/cropedImage.png", cropedImg);
I'm new to image processing and development. I need to take the inside triangle pixels of the image. In order to do it I used the following code. Unfortunately I obtain unwanted black pixels. get rid of that problem i tried to remove background[0] pixels by giving alfa value.(tranparent background) But it gives following Error. Any help is appreciated.
My code:
Mat img = cv::imread("/home/fabio/code/lena.jpg", cv::IMREAD_GRAYSCALE);
Mat alpha(img.size(), CV_8UC1, Scalar(0));
//triangle definition (example points)
vector<Point> points;
points.push_back(Point(200, 70));
points.push_back(Point(60, 150));
points.push_back(Point(500, 500));
//apply triangle to mask
fillConvexPoly(alpha, points, Scalar(255));
cv::Mat finalImage = cv::Mat::zeros(img.size(), img.type());
img.copyTo(finalImage, alpha);
imshow("image", finalImage);
Mat dst;
Mat rgb[1];
split(finalImage, rgb);
Mat rgba[2] = { finalImage, alpha };
merge(rgba, 2, dst);
imshow("dst", dst);
Error: OpenCV Error: Bad number of channels (Source image must have 1, 3 or 4 channels) in cvConvertImage, file C:\builds\2_4_PackSlave-win64-vc12-shared\opencv\modules\highgui\src\utils.cpp, line 611
use this instead of your last block:
std::vector<cv::Mat> channels;
cv::split(finalImage,m channels);
if(channels.size() == 0)
{
std::cout << "unexpected error" << std::endl;
return 1;
}
// fill up to reach 3 channels
while(channels,size() < 3)
{
channels.push_back(channels[0]);
}
// add alpha channel
channels.push_back(alpha);
cv::merge(channels, dst);
I didn't test it but this should be what you want?
I have image as follows:
I want to detect 5 dials for processing. Hough circles is detecting all other irrelevant circles. to solve this i created a plain image and generated absolute difference with this one. It gave this image:
I drew box around it and final image is:
My code is as follows:
Mat img1 = imread(image_path1, COLOR_BGR2GRAY);
Mat img2 = imread(image_path2, COLOR_BGR2GRAY);
cv::Mat diffImage;
cv::absdiff(img2, img1, diffImage);
cv::Mat foregroundMask = cv::Mat::zeros(diffImage.rows, diffImage.cols, CV_8UC3);
float threshold = 30.0f;
float dist;
for(int j=0; j<diffImage.rows; ++j)
{
for(int i=0; i<diffImage.cols; ++i)
{
cv::Vec3b pix = diffImage.at<cv::Vec3b>(j,i);
dist = (pix[0]*pix[0] + pix[1]*pix[1] + pix[2]*pix[2]);
dist = sqrt(dist);
if(dist>threshold)
{
foregroundMask.at<unsigned char>(j,i) = 255;
}
}
}
cvtColor(diffImage,diffImage,COLOR_BGR2GRAY);
Mat1b img = diffImage.clone();
// Binarize image
Mat1b bin = img > 70;
// Find non-black points
vector<Point> points;
findNonZero(bin, points);
// Get bounding rect
Rect box = boundingRect(points);
// Draw (in color)
rectangle(img1, box, Scalar(0,255,0), 3);
// Show
imshow("Result", img1);
Now the issue is i cant compare plain image with anyother iamge of different sizes. Any pointer to right direction will be very helpful.
Regards,
Saghir A. Khatr
Edit
My plain image is as follows
I want to create a standard sample plain image which can be used with any image to detect that portion...
Hi
I have read the openCV reference from this site and using the following code:
VideoCapture mCap;
Mat mcolImage, mbwImage;
mCap >> mcolImage; // New frames from the camera
cvtColor( mcolImage, mcolImage, CV_BGR2RGB);
cvtColor( mcolImage, mbwImage, CV_RGB2GRAY);
QImage colImagetmp( (uchar*)mcolImage.data, mcolImage.cols, mcolImage.rows, mcolImage.step,
QImage::Format_RGB888 ); //Colour
QImage bwImagetmp ( (uchar*)mbwImage.data, mbwImage.cols, mbwImage.rows, mbwImage.step,
QImage::Format_Indexed8); //Greyscale. I hope
ui.bwDisplay->setPixmap(QPixmap::fromImage(bwImagetmp));
ui.colDisplay->setPixmap( QPixmap::fromImage(colImagetmp ));
I'm trying to convert one of the output into greyscale. Unfortunately they're still both in colour and I can't see that I've missed a step somewhere.
Thanks for the help.
You need to explicitly set a gray color table for bwImagetmp:
QVector<QRgb> colorTable;
for (int i = 0; i < 256; i++) colorTable.push_back(qRgb(i, i, i));
bwImagetmp.setColorTable(colorTable);