Does anyone know if OpenCV has some kind of texture descriptors implemented? I googled "opencv texture descriptors" but not much to see.
Thanks in advance.
You can use the Gabor filter to extract texture descriptors
cv::Mat kernel = cv::getGaborKernel(cv::Size(kernel_size,kernel_size), sig, th, lm, gm, ps);
cv::filter2D(src_f, dest, CV_32F, kernel);
This is the C++ code, but it's the same for every other language. You have to get the Gabor filter kernel and than use the filter2d function.
I hope it helps
Related
I am new to image processing and trying to get the contours of the apples in these images. To do so, i use openCV. But i do not get a propper contour detection. I want the algorithm also be able to get contours of other objects. So not limmited to apples (= circles).
Original picture
If i follow the instructions there are 4 steps to be taken.
Open the image file
Convert the file to grayscale
Do some processing (blur, errode, dillitate, you name it)
Get the contours
The first point that confuses me is the grayscale conversion.
I did:
Mat image;
Mat HSVimage;
Mat Grayimage;
image = imread(imageName, IMREAD_COLOR); // Read the file
cvtColor(image, HSVimage, COLOR_BGR2HSV);
Mat chan[3];
split(HSVimage, chan);
Grayimage = chan[2];
First question:
Is this correct choice, or shoud i just read the file in Grayscale or use YUV ?
I only use 1 channel of the HSV, is this correct ?
I tried alot of processing methodes, but there are so many i lost track. The best result i got was when i used a treshold and an adaptiveTreshold.
threshold(Grayimage, Grayimage,49, 0, THRESH_TOZERO);
adaptiveThreshold(Grayimage, Tresholdimage, 256, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 23, 4);
The result i get is:
result after processing
But a find contours does not find a closed object. So i get:
contours
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(Tresholdimage, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
I tried hough cicles,
vector<Vec3f> circles;
HoughCircles(Tresholdimage, circles, HOUGH_GRADIENT, 2.0, 70);
and i got:
hough circles ok
So i was a happy man, but as soon is i tried the code on an other picture, i got:
second picture original
hough circles wrong
I can experiment with the HoughCircles function i see there are alot of posibilities, but i can only detect circles with it, so it is not my first choice.
I am a newbie at this. My questions are:
Is this a correct way or is it better to use technics like blob detection or ML to find the objects in the picture ?
If it is a correct way, what functions should i use to get the better results ?
Regards,
Peter
Im new to OpenCV, Im trying to use SIFT to extract key points from a grayscale image. But failing to successfully compile the code. There seems to be no clear help on the internet for usage of SIFT. Pls help. Thanks.
while(true)
{
Mat myFrame;
Mat grayFrame;
capture.read(myFrame);
cvtColor(myFrame, grayFrame, CV_BGR2GRAY);
vector<Vec2f> outputArray;
vector<KeyPoint> keypoint;
Feature2D EXTRACTOR;
Mat descriptors;
EXTRACTOR.detectAndCompute(grayFrame, outputArray, keypoint, descriptors);
}
vector<KeyPoint> keyVector;
Mat outputDiscriptor;
Ptr<SIFT> detector = SIFT::create();
detector->detect(grayFrame, keyVector);
//here grayFrame is the gray scale of the original frame/image
if you want to get the descriptors of the key points use the
detector->compute(grayFrame, keyVector)
I want to use the Gabor feature to do some classification job. But the OpenCV do not support this function. Would you give some idea for implementing this function. OpenSource library is also OK. Thanks in advance.
oh, there is a gabor kernel in opencv:
#include "opencv2/imgproc/imgproc.hpp"
cv::Mat kernel = cv::getGaborKernel(cv::Size(kernel_size,kernel_size), sig, th, lm, gm, ps);
Mat src_f; // img converted to float
Mat dest;
cv::filter2D(src_f, dest, CV_32F, kernel);
Mat fourierTransform(1,final.size()-1, CV_64FC1);
//Mat fourierTransform;
Mat ans(1,final.size()-1, CV_64FC1)
cv::dft(signal, fourierTransform,cv::DFT_COMPLEX_OUTPUT);
I am following this approach and then I am stuck at how to obtain the complex part of DFT. Can anybody tell how to about it to obtain it. Thanks in advance.
Here is a tutorial on how you can use OpenCV's DFT function:
Discrete Fourier Transform
Essentially, it will store the output matrix as a two-channel matrix. The first channel is for real values, and the second channel is for complex values.
I'm throwing this out there in hope that someone will have attempted something this ridiculous before. My goal is to take in an input image, and segment it based upon the standard deviation of a small window around each pixel. Bascially, this should mathematically resemble a gauss or box filter, in that it will be applied to a compile time (or even run-time) user specified window size around each pixel, and the destination array will contain the SD information at each pixel, in an image the same size as the original.
The idea is to do this on an image in HSV space, so that I can easily find regions of homogeneous color (i.e. those with small local SDs in the Hue and Sat planes) and extract them from the image for more in-depth processing.
So the question is, has anyone ever built a custom filter like this before? I don't know how to do the SD in a simple box type filter kernel like the ones used for gauss and blur, so I'm guessing I'll have to use the FilterEngine construct. Also, I forgot to mention I'm doing this in C++.
Your advice and musings are much appreciated.
Wikipedia has a nice explanation of standard deviation, which you can use to for a standard deviation filter.
Basically, it boils down to blurring the image with a box filter, blurring the square of the image with a box filter, and taking the square root of their difference.
UPDATE: This is probably better shown with the equation from Wikipedia...
You can think of the OpenCV blur function as representing the expected value (i.e., E[X] a.k.a. the sample mean) of the neighborhood of interest. The random samples X in this case are represented by image pixels in the local neighborhood. Therefore, by using the above equivalence we have something like sqrt(blur(img^2) - blur(img)^2) in OpenCV. Doing it this way allows you to compute the local means and standard deviations.
Also, just in case you are curious about the mathematical proof. This equivalence is known as the computational formula for variance.
Here is how you can do this in OpenCV:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
Mat mat2gray(const Mat& src)
{
Mat dst;
normalize(src, dst, 0.0, 1.0, NORM_MINMAX);
return dst;
}
int main()
{
Mat image = imread("coke-can.jpg", 0);
Mat image32f;
image.convertTo(image32f, CV_32F);
Mat mu;
blur(image32f, mu, Size(3, 3));
Mat mu2;
blur(image32f.mul(image32f), mu2, Size(3, 3));
Mat sigma;
cv::sqrt(mu2 - mu.mul(mu), sigma);
imshow("coke", mat2gray(image32f));
imshow("mu", mat2gray(mu));
imshow("sigma",mat2gray(sigma));
waitKey();
return 0;
}
This produces the following images:
Original
Mean
Standard Deviation
Hope that helps!
In case you want to use this in more general way this can produce nan values
Values close to zero can be sometimes "negative".
Mat sigma;
cv::sqrt(mu2 - mu.mul(mu), sigma);
correct way should be
Mat sigma;
cv::sqrt(cv::abs(mu2 - mu.mul(mu)), sigma);