I write a simple app in OpenCV that delete black background of an image and save it with white background in JPG. However, it's always saved with black background.
This is my code:
Mat Imgsrc = imread("../temp/temp1.jpg",1) ;
mat dest;
Mat temp, thr;
cvtColor(Imgsrc, temp, COLOR_BGR2GRAY);
threshold(temp,thr, 0, 255, THRESH_BINARY);
Mat rgb[3];
split(Imgsrc,rgb);
Mat rgba[4] = { rgb[0],rgb[1],rgb[2],thr };
merge(rgba,4,dest);
imwrite("../temp/r5.jpg", dest);
You can simply use setTo with a mask to set some pixels to a specific value according to a mask:
Mat src = imread("../temp/temp1.jpg",1) ;
Mat dst;
Mat gray, thr;
cvtColor(src, gray, COLOR_BGR2GRAY);
// Are you sure to use 0 as threshold value?
threshold(gray, thr, 0, 255, THRESH_BINARY);
// Clone src into dst
dst = src.clone();
// Set to white all pixels that are not zero in the mask
dst.setTo(Scalar(255,255,255) /*white*/, thr);
imwrite("../temp/r5.jpg", dst);
Also a few notes:
You can directly load an image as grayscale using: imread(..., IMREAD_GRAYSCALE);
You can avoid to use all those temporary Mats.
Are you sure you want to use 0 as threshold value? Because in this case you can avoid entirely to apply theshold, and set to white all pixels that are 0 in the grayscale image: dst.setTo(Scalar(255,255,255), gray == 0);
This is how I'd do:
// Load the image
Mat src = imread("path/to/img", IMREAD_COLOR);
// Convert to grayscale
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
// Set to white all pixels that are 0 in the grayscale image
src.setTo(Scalar(255,255,255), gray == 0)
// Save
imwrite("path/to/other/img", src);
Related
I need to detect the defects which are more grayish in color.
I have tried removing noise from the image, thresholding the image but due to gray color of the defect, it becomes invisible or only the boundary remains. I don't know how to detect the defects , if I apply dilation it gets mixed with the surrounding circles.
Images with defects:
Images without defect:
My original image with the red pen marked defect is :
I have tried the below code:
//convert to grayscale
Mat gray_img;
cv::cvtColor(r_img, gray_img, COLOR_BGR2GRAY);
Mat dst1, dst2, dst;
cv::blur(gray_img, dst1, Size(3, 3));
cv::blur(gray_img, dst2, Size(7, 7));
cv::subtract(dst1, dst2, dst);
//thresholding
Mat thresh;
adaptiveThreshold(dst, thresh, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 5, 5);
Mat inv_thresh;
bitwise_not(thresh, inv_thresh);
My thresholded image is
i want to draw the canni result on the original image. How can i do this? i tried like this, but an error comes out
Mat image;
image = imread("C:\\test.jpg",1);
Mat gray, edqes, out;
cvtColor(image, gray, COLOR_BGR2GRAY);
Canny(gray, edqes, 100, 200, 3);
out.copyTo(image,edqes);
cvNamedWindow("original",CV_WINDOW_NORMAL);
cvNamedWindow("binary",CV_WINDOW_NORMAL);
cvNamedWindow("canny",CV_WINDOW_NORMAL);
cvNamedWindow("out",CV_WINDOW_NORMAL);
imshow("original",image);
imshow("binary", gray);
imshow("canny", edqes);
imshow("out", out);
cvWaitKey(0);
cvDestroyAllWindows();
Try:
cvtColor(edqes, edqes, COLOR_GRAY2BGR);
bitwise_or(edqes,image,out);
For example, I create
Mat mat1 = Mat::zeros(Size(100, 100), CV_8UC3);
and fill each pixel with (0, 255, 255), which is supposed to be red in hsv.
However, if I imshow this mat, this will be printed as a BGR image and is not red.
How do I make this mat hsv format and setting (0, 255, 255) result in red?
imshow assumes that the image you pass to it is in BGR color space. However, you can create a small function that does your imshow of HSV images.
void imshowHSV(std::string& name, cv::Mat& image)
{
cv::Mat hsv;
cv:cvtColor(image, hsv, CV_HSV2BGR);
cv::imshow(name, hsv);
}
But beware! this will convert and create a copy of the image, if you over use it it may have quite some overhead :)
I want to make matrix multiplication between image and mask. I want multiply in HSV value with 0.3. I think, the problem is between CV_32FC3 and CV_8UC3, but when I convert, still not work correct.
How can I do? Here is my current code:
Mat mask = Mat(frame.size(), CV_32FC3, cv::Scalar(1, 1, 1));
cv::fillConvexPoly(mask, pts, 3, cv::Scalar(1,1,0.3));
cvtColor(frame, frame, CV_BGR2HSV);
frame.convertTo(frame, CV_32FC3);
cv::multiply(frame,mask,frame);
frame.convertTo(frame, CV_8UC3);
cvtColor(frame, frame, CV_HSV2BGR);
If I do only this, see the mask is ok - white and black changes:
Mat mask = Mat(frame.size(), CV_32FC3, cv::Scalar(1, 1, 1));
cv::fillConvexPoly(mask, pts, 3, cv::Scalar(0,0,0));
imshow("mask", mask);
I convert an rgb image to hsv
I used the function inRange() to detect the red color in the image
Now I want to recognize color instead of detection:
- I want to compare the hue value against the range of red color .. if it lies within it .. print red
else if it lies in blue range say blue .. so on
How to compare Mat hue if it is in the range 100 to 180??
int main()
{
Mat image;
image = imread("C:/Users/Maram/Documents/Visual Studio 2013/Projects/firsttrialw310/x64/Debug/carcolor.png", CV_LOAD_IMAGE_COLOR);
if (!image.data)
{
cout << "Could not open or find the image" << std::endl;
return -1;
}
// Create a new matrix to hold the HSV image
Mat HSV;
// convert RGB image to HSV
cvtColor(image, HSV, CV_RGB2HSV);
namedWindow("Display window", CV_WINDOW_AUTOSIZE);
imshow("Display window", image);
namedWindow("Result window", CV_WINDOW_AUTOSIZE);
imshow("Result window", HSV);
vector<Mat> hsv_planes;
split(HSV, hsv_planes);
Mat h = hsv_planes[0]; // H channel
Mat s = hsv_planes[1]; // S channel
Mat v = hsv_planes[2]; // V channel
namedWindow("hue", CV_WINDOW_AUTOSIZE);
imshow("hue", h);
namedWindow("saturation", CV_WINDOW_AUTOSIZE);
imshow("saturation", s);
namedWindow("value", CV_WINDOW_AUTOSIZE);
imshow("value", v);
//// red color range
Scalar hsv_l(100, 150, 150);
Scalar hsv_h(180, 255, 255);
Mat bw;
inRange(HSV, hsv_l, hsv_h, bw);
imshow("Specific Colour", bw);
////
//black cv::Scalar(0, 0, 0, 0), cv::Scalar(180, 255, 40, 0)
//white cv::Scalar(0, 0, 80, 0), cv::Scalar(180, 255, 255, 0)
waitKey(0);
return 0;
}