I am new to working in openCV. I was trying to detect features in an image using goodFeaturesToTrack() in c++ in a colored image but it gave me the following error:
" OpenCV Error: Assertion failed (src.type() == CV_8UC1 || src.type() == CV_32FC1) in cv::cornerEigenValsVecs, file D:\cs436\opencv-3.2.0\modules\imgproc\src\corner.cpp, line 287 "
Then I tried it on a greyscale image and it found the features. Can anyone please tell if we can use the function on a colored image? and what does the error mean?
From the documentation of goodFeaturesToTrack(), the image parameters takes in a 8-bit or 32-bit single channel image. single channel implies grayscale.
So yes, the function only works for grayscale images. The error message also indicates that by saying that the src.type() must have 1 channel as indicated by CV_8UC1 and CV_32FC1
That right the function is defined for grayscale images only. To apply colored images you have to convert the rgb image to a grayscaled image by:
cv::cvtColor(rgbImage, grayImage, CV_BGR2GRAY);
Related
I am using Network Optix Video management service. Using their application I am building a plugin. For my purpose I want to export frame as an image from a video. for that I used following code to convert to cv object and saving into my file.
cv::Mat img_color;
cv::Mat img(
videoFrame->height(),/*_rows*/
videoFrame->width(), /*_cols*/
CV_8UC1, //< BGR color space (default for OpenCV) /*_type*/
(void*) videoFrame->data(0), /*_data*/
(size_t) videoFrame->lineSize(0)); /*_step*/
cv::cvtColor(img, img_color, CV_GRAY2RGB);
m_lastVideoFrameTimestampUs = videoFrame->timestampUs();
std::string file_path = "/var/www/html/images/"+std::to_string(m_lastVideoFrameTimestampUs)+".jpg";
cv::imwrite(file_path,img_color);
below screenshot is what I am getting on Network Optix client application.
But, this is what I am getting as an image file on my machine.
cvtColor doesn't have any effect on the image
I think, CV_8UC1 argument should be modified so that I will get RGB image
EDIT - 1:
changes CV_8UC1 to CV_8UC3
Result turned into 3 segments of image
CV_8UC1 means that it is 8-bit single-channel array, you are getting a grayscale image at first and you can not except cvtColor to get it colorized again. cvtColor which you used will convert the image to BGR but all the channels will be in same value so it will continue to seem as grayscale.
In this case you can use CV_8UC3 which means that it is an 8-bit unsigned integer matrix/image with 3 channels(If your image in 3 channels)
I have a png image which is in grayscale 'test.png'. I need apply adaptive threshold to this image. I am using OpenCV.
image = cv2.imread('test_big.png')
im = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
I am not able to apply adaptive threshold since the image is not in grayscale.
So I tried to read the image as grayscale:
image = cv2.imread('test_big.png',1)
Now I can apply adaptive threshold but the output will be a blue and red image instead of black and white. Can anyone help?
The fault lies in the second code snippet:
image = cv2.imread('test_big.png',1)
Although you have said that test_big.png is a grayscale image, you have declared it as a color image (RGB) with three channels.
Hence you have to change the code to
image = cv2.imread('test_big.png', 0)
0 -> grayscale image
1 -> color image
You can also try:
cv2.imread('test_big.png', cv2.IMREAD_GRAYSCALE)
The bottom line is: although the image being read is a grayscale image, the system will not recognize it until it is explicitly specified. In your case, your image was a grayscale image, but since you declared it as a color image it considered the image to have three channels (RGB) and hence the subsequent adaptive threshold function did not execute.
I'm trying to use C++ and OpenCV to combine pictures, but an error occurs.
My code:
The error:
Assertion failed (size.width>0 && size.height>0) in imshow
What is the 199 in imread(..., 199) supposed to mean?
Valid values are:
IMREAD_UNCHANGED If set, return the loaded image as is (with alpha channel, otherwise it gets cropped).
IMREAD_GRAYSCALE If set, always convert image to the single channel grayscale image.
IMREAD_COLOR If set, always convert image to the 3 channel BGR color image.
IMREAD_ANYDEPTH If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
IMREAD_ANYCOLOR If set, the image is read in any possible color format.
IMREAD_LOAD_GDAL If set, use the gdal driver for loading the image.
a few other options for reduced grayscale images.
Usually you want to load the image in BGR:
Mat img = imread("/path/to/img.png"); // IMREAD_COLOR is default value
or in grayscale
Mat img = imread("/path/to/img.png", IMREAD_GRAYSCALE);
I just want to do convert a gray image to a binary image. But threshold function gives me a totaly black image as a binary image. I want to get dark gray object.
What is wrong here?
Code:
Mat theFrame = imread("C:\\asdsss.png"); // opencv
Mat gray,binary;
cvtColor(theFrame, gray, CV_BGR2GRAY);
threshold(gray, binary, 150, 255, THRESH_BINARY);
imwrite("result.jpg",binary);
İnput image:
The code works perfectly fine. I ran you exact code on the image provided. There is no issue with it.
I got the following output by running your code. The only problem I can think of could be loading of image. Try to see your image using cv::imshow after loading it. Also try to convert your image into jpg format and then try loading it again. You can also try compiling and running the opencv thresholding sample.
I wrote a code for watershed segmentation in C API. Now I am converting all those into C++. so, cvsaveimage becomes imwrite. But when I use imwrite ,all i get is a black image.
this is the code:-
Mat img8bit;
Mat img0;
img0 = imread("source.png", 1);
Mat wshed(img0.size(), CV_32S);
wshed.setTo(cv::Scalar::all(0));
////after performing watershed segmentation and
// displaying the watershed image from wshed//
wshed.convertTo(img8bit, CV_32FC3, 255.0);
imwrite("Watershed.png", img8bit);
The original image that I want to save is in wshed. I saw suggestions from the net that we need to convert it to 16 bit or higher so that the imwrite saves it right. Like you see,I tried that. But the wshed image is being displayed correctly when using imshow.The img0 is grey image/black and white while the wshed image is coloured. any help on this?
Edit- I changed the 4th line to
Mat wshed(img0.size(), CV_32FC3);
When calling Mat::convertTo() with a scalar (255 in your case), the values of every matrix item will be multiplied by this scalar value. This will cause all most every result pixel values exceed 255 (i.e. white pixels) except those of 0s where they remain 0 (i.e. black pixels). This is why you will get the black-white pixel in the end.
To make it work, simply change it to:
wshed.convertTo(img8bit, CV_32FC3);
You said:
The original image that I want to save is in wshed. I saw suggestions
from the net that we need to convert it to 16 bit or higher so that
the imwrite saves it right.
If saving the image does not work you should keep in mind that the image data has to be either 8-Bits or 16-Bit unsigned when using the imwrite Function, not 16-Bits or higher.
This is stated in the documentation:
The function imwrite saves the image to the specified file. The image
format is chosen based on the filename extension (see imread() for the
list of extensions). Only 8-bit (or 16-bit unsigned (CV_16U) in case
of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with ‘BGR’
channel order) images can be saved using this function. If the format,
depth or channel order is different, use Mat::convertTo() , and
cvtColor() to convert it before saving. Or, use the universal
FileStorage I/O functions to save the image to XML or YAML format.