cvSobel problems - opencv - opencv

i've got the code below:
// Image Processing.cpp : Defines the entry point for the console application.
//
//Save an available image.
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
/*
The purpose of this program is to show an example of THRESHOLDING.
*/
int _tmain(int argc, _TCHAR* argv[])
{
IplImage* src = cvLoadImage("D:\\document\\Study\\university of technology\\semester_8\\Computer Vision\\Pics for test\\black-white 4.jpg");
IplImage* dst = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);
IplImage* temp1 = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
IplImage* temp2 = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
cvCvtColor(src,temp1,CV_RGB2GRAY);
cvSobel(temp1,temp2,0,1,3);
cvMerge(temp2,temp2,temp2,NULL,dst);
cvNamedWindow("src",1);
cvNamedWindow("dst",1);
cvShowImage("src",src);
cvShowImage("dst",temp2);
cvWaitKey(0);
cvReleaseImage(&src);
//cvReleaseImage(&dst);
cvDestroyAllWindows();
return 0;
}
when i run it, there's an warning as the picture below:
but if i still click on "countinue" button, the result is displayed!
hope someone can give me an explaination !

The result is correct. The description of the program is not. Your xorder=0 and yorder=1 which means that you are detecting the first derivative in the y-direction. The white pixels in the image correspond to boundaries that can be detected by a vertical derivative, namely as close to horizontal boundaries as possible. This is why the vertical lines are barely ever detected.
CvSobel by itself has NOTHING to do with thresholding. CvSobel is a function used for finding boundaries and contours. Thresholding is most commonly an operation that creates a black-and-white image from a greyscale image. It is also called image binarization.
If you want to threshold an image, start with cvThreshold and cvAdaptiveThreshold.

i've fixed it, here is my code:
// Image Processing.cpp : Defines the entry point for the console application.
//
//Save an available image.
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
/*
The purpose of this program is to show an example of Sobel method.
*/
int _tmain(int argc, _TCHAR* argv[])
{
IplImage* src = cvLoadImage("D:\\document\\Study\\university of technology\\semester_8\\Computer Vision\\Pics for test\\black-white 4.jpg");
IplImage* dst = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
IplImage* dst_x = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
IplImage* dst_y = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
IplImage* temp1 = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
IplImage* temp2 = cvCreateImage(cvGetSize(src),IPL_DEPTH_16S,1);
cvCvtColor(src,temp1,CV_RGB2GRAY);
cvSobel(temp1,temp2,0,1,3);
cvConvertScale(temp2,dst_y,1.0,0);
cvSobel(temp1,temp2,1,0,3);
cvConvertScale(temp2,dst_x,1.0,0);
//k nen dao ham cung luc theo x va y ma nen dao ham rieng roi dung ham cvAdd.
//cvSobel(temp1,temp2,1,1,3);
//cvConvertScale(temp2,dst,1.0,0);
cvAdd(dst_x,dst_y,dst,NULL);
cvNamedWindow("src",1);
cvNamedWindow("dst",1);
cvNamedWindow("dst_x",1);
cvNamedWindow("dst_y",1);
cvShowImage("src",src);
cvShowImage("dst",dst);
cvShowImage("dst_x",dst_x);
cvShowImage("dst_y",dst_y);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&dst);
cvReleaseImage(&temp1);
cvReleaseImage(&temp2);
cvDestroyAllWindows();
return 0;
}

Related

OpenCV convexityDefects drawing

Hi. I have the above image and use the "findContours" function.
And then I use the "convexity defects" functions to find the corner points.
The result is as follows.
The problem with this code is that it can not find the rounded corners.You can not find a point like the following.
This is my code
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
#include <iostream>
#include <sstream>
#include <fstream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
cv::Mat image = cv::imread("find_Contours.png");
//Prepare the image for findContours
cv::cvtColor(image, image, CV_BGR2GRAY);
cv::threshold(image, image, 128, 255, CV_THRESH_BINARY);
//Find the contours. Use the contourOutput Mat so the original image doesn't get overwritten
std::vector<std::vector<cv::Point> > contours;
cv::Mat contourOutput = image.clone();
cv::findContours(contourOutput, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
////convexityDefects
vector<vector<Point> >hull(contours.size());
vector<vector<int> > hullsI(contours.size()); // Indices to contour points
vector<vector<Vec4i>> defects(contours.size());
for (int i = 0; i < contours.size(); i++)
{
convexHull(contours[i], hull[i], false);
convexHull(contours[i], hullsI[i], false);
if (hullsI[i].size() > 3) // You need more than 3 indices
{
convexityDefects(contours[i], hullsI[i], defects[i]);
}
}
///// Draw convexityDefects
for (int i = 0; i < contours.size(); ++i)
{
for (const Vec4i& v : defects[i])
{
float depth = v[3]/256;
if (depth >= 0) // filter defects by depth, e.g more than 10
{
int startidx = v[0]; Point ptStart(contours[i][startidx]);
int endidx = v[1]; Point ptEnd(contours[i][endidx]);
int faridx = v[2]; Point ptFar(contours[i][faridx]);
circle(image, ptFar, 4, Scalar(255, 255, 255), 2);
cout << ptFar << endl;
}
}
}
//
cv::imshow("Input Image", image);
cvMoveWindow("Input Image", 0, 0);
//
waitKey(0);
}
Can someone make the code and find the red dot? please help.
now i want find "convexity defects" from inside,not outside like this image:
Someone can help me??
It is very important to use
convexHull(contours[i], hullsI[i], true);
That is, with the last argument "true" for indices. I'm almost certain this is the reason it cannot find all the defects. Before fixing this, it is not much sense try to find other bugs (if any).

HDR image reading and writing in opencv

I had written code for hdr image reading in opencv whenever i try to compile that i am getting ‘TonemapDurand’ was not declared in this scope
this type of error.
#include"opencv2/opencv.hpp"
#include "vector"
#include "bits/stdc++.h"
#include "fstream"
using namespace cv;
int main(int argc, char** argv )
{
vector<Mat>images;
Mat image;
image = imread( argv[1], 1 );
images.push_back(image);
Mat ldr;
Ptr<TonemapDurand> tonemap = createTonemapDurand(2.2f);
tonemap->process(images[0], ldr);
imwrite("ldr.png", ldr * 255);
waitKey(0);
return 0;
}
It looks like there is no HDR support in OpenCV 2.4.9, as you can see from here.
You have to install OpenCV 3 for doing your experiments on HDR.
There is a nice blog on using HDR in OpenCV here
It looks like you have missed some includes in your code :
#include <opencv2/photo.hpp>

split a BGR matrix without use split() function

I am programming with Visual Studio 2012 and the Opencv library, in the 2.4.6 version.
Someone can help me about splitting a BGR image into three images, one for every channel?
I know that there is the split function in OpenCV, but it causes me an unhandled exception, probably because I have a 64 bit processor with the 32 bit library, or probably it's the version of the library, so I want to know how to iterate on the pixel values of a BGR matrix without use split().
Thanks in advance.
If you don't want to use split() then you can read each r,g,b pixel value from your source image and write to destination image and which should be single channel.
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, const char** argv ){
Mat src = imread("ball.jpg", 1);
Mat r(src.rows,src.cols,CV_8UC1);
Mat g(src.rows,src.cols,CV_8UC1);
Mat b(src.rows,src.cols,CV_8UC1);
for(int i=0;i<src.rows;i++){
for(int j=0;j<src.cols;j++){
Vec3b pixel = src.at<Vec3b>(i, j);
b.at<uchar>(i,j) = pixel[0];
g.at<uchar>(i,j) = pixel[1];
r.at<uchar>(i,j) = pixel[2];
}
}
imshow("src", src);
imshow("r", r);
imshow("g", g);
imshow("b", b);
waitKey(0);
}

How to obtain a contour from points with OpenCV

I'm trying to obtain a ROI from an image using VC++ and OpenCV.
I managed to display an image, get the coordinates of a point when I click on it, store these coordinates in a vector and draw lines between these points on my image.
Here is my code:
//Includes
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stdio.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
static int app;
static vector<Point2f> cont(6);
static Mat img = imread("C:/img.jpg",0);
void on_mouse(int, int, int, int, void* );
int main()
{
app = 0;
namedWindow("myWindow", CV_WINDOW_AUTOSIZE);
cvSetMouseCallback("myWindow", on_mouse, 0);
imshow("myWindow", img);
waitKey(0);
}
void on_mouse(int evt, int x, int y, int flags, void* param)
{
if(evt == CV_EVENT_LBUTTONDOWN)
{
Point pt(x,y);
if(app<6)
{
cont[app]=pt;
app++;
}
cout<<"Coordonnees du point pt : "<<x<<","<<y<<endl;
for (int i=0; i<6;i++)
{cout<<cont[i]<<endl;}
}
if(evt == CV_EVENT_RBUTTONDOWN)
{
for (int j=0;j<5;j++)
{
line(img,cont[(j)],cont[(j+1)],CV_RGB(255,0,0),2);
}
line(img,cont[(5)],cont[(0)],CV_RGB(255,0,0),2);
imshow("myWindow", img);
}
}
What I would like to obtain is a vector that contains the coordinates of all the points of the contour and ultimately a bianary matrix the size of my image that contains 0 if the pixel is not in the contour, else 1.
Thanks for your help.
Make single element vector< vector< Point> > and then use drawContours with CV_FILLED. Then you will have binary matrix you wanted.
I currently don't have IDE but code will be like following
vector< vector< Point> > contours;
contours.push_back(cont);//your cont
Mat output(img.rows,img.cols,CV_8UC1);//your img
drawContours(output, contours, 0, Scalar(1), CV_FILLED);//now you have binary image

weird binary image values generated by cvThreshold

Hey, guys, i am using opencv to do some vehicle recognition work, and when i use cvThershold to convert the gray image to binary image, the return image is really strange, the binary image supposes to have only two values,0 and 255, however, it contains other values like 2,3,254,253, anyone knows how this happens, and also cvCmps also has this problem.
cvThreshold has a variety of behaviours beyond normal binary thresholding. They are described in the OpenCV API reference.
For example, if you call it with the flag threshold_type set CV_THRESH_TRUNC, it will truncate all intensities above the specified threshold only. The intensities below the threshold will remain untouched. Perhaps this accounts for your strange result?
If you post the image and your code (the bit that calls cvThreshold is enough) I could probably be of more help.
Try this:
/*
* compile with:
*
* g++ -Wall -ggdb -I. -I/usr/include/opencv -L /usr/lib -lm -lcv -lhighgui -lcvaux threshold.cpp -o threshold.out
*/
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <assert.h>
IplImage *
threshold(IplImage const *in, int threshold)
{
assert(in->nChannels == 1);
CvSize size = cvSize(in->width, in->height);
IplImage *out = cvCreateImage(size, IPL_DEPTH_8U, 1);
cvThreshold(in, out, threshold, 255, CV_THRESH_BINARY);
return out;
}
void
show_image(char const *title, IplImage const *image)
{
cvNamedWindow(title, CV_WINDOW_AUTOSIZE);
cvShowImage(title, image);
cvWaitKey(0);
cvDestroyWindow(title);
}
int
main(int argc, char **argv)
{
if (argc < 2)
{
fprintf(stderr, "usage: %s in.png\n", argv[0]);
return 1;
}
IplImage *in = cvLoadImage(argv[1]);
IplImage *grey = in;
if (in->nChannels != 1)
{
/*
* For some reason, cvCreateImage returns an image with 3 channels even
* when a greyscale image is specified (e.g. PGM). Hack around this by
* just taking the first channel of the image. OpenCV uses BGR order,
* so it will be the B channel.
*/
CvSize size = cvSize(in->width, in->height);
grey = cvCreateImage(size, IPL_DEPTH_8U, 1);
cvSplit(in, grey, NULL, NULL, NULL);
cvReleaseImage(&in);
}
IplImage *thres = threshold(grey, 127);
show_image("thresholded", thres);
cvReleaseImage(&thres);
cvReleaseImage(&grey);
return 0;
}
Give it any image (even a colour one, see comment for clarification), e.g. [this one][1]. Do you get the expected result?
[1]: http://r0k.us/graphics/kodak/kodak/kodim20.png SixShooter

Resources