Out of Index Error when reading Image with OpenCV using Pointer - opencv

I receive a weird out of range error when reading an 16-bit RGB image with openCV. The image has a resolution of 2700 x 2000. Outer rows and columns of the image are black.
I got the following code:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
// Create Mat Container and rowPtr
Mat image;
image = imread(argv[1], -1);
uint16_t* rowPtr;
// Read Image characteristics
int width = image.cols;
int height = image.rows;
int numChannels = image.channels();
if (image.isContinuous())
{
std::cout << "isContinuous!" << "\n";
width *= height;
height = 1;
}
// Double for loop, reading using pointers according to
// https://docs.opencv.org/2.4/doc/tutorials/core/how_to_scan_images/how_to_scan_images.html
for ( uint32_t y = 0; y < height; ++y )
{
rowPtr = image.ptr<uint16_t>(y);
for ( uint32_t x = 0; x < width; ++x )
{
const uint32_t idx = x + y * width;
// Quick Debug
if (idx > 2704713)
{
std::cout << "height : " << height << "\n";
std::cout << "width : " << width << "\n";
std::cout << "row : " << y << "\n";
std::cout << "col : " << x << "\n";
std::cout << "idx : " << idx << "\n";
std::cout << "B: " << rowPtr[numChannels * idx + 0] << "\n";
std::cout << "G: " << rowPtr[numChannels * idx + 1] << "\n";
std::cout << "R: " << rowPtr[numChannels * idx + 2] << "\n"; //The error occurs here!
}
}
}
namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display.
imshow( "Display window", image ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
The output of running the code is:
isContinuous!
height : 1
width : 5400000
row : 0
col : 2704714
idx : 2704714
B: 0
G: 0
So, the segmentation fault happens, when the value for R should be read, at Pixel No. 2,704,715.
This code runs without problems for images that don't exhibit large black borders. So I thought that openCV's imread might crop such images internally, leading to such an error?

Related

How to track the 2d points over the images for 3d-reconstruction as specified in opencv sfm pipeline?

I am trying to do 3D reconstruction using this code from opencv. As far as I understood, I need a textfile with the 2D points as per the given format. I am wondering if anyone could help me in getting these 2D points they mention in this program. I have a set of images with the calibration parameters but I have been not able to understand how could I track and save these 2D points e.g. the first point in frame 1 is the same point in frame 2 in the format they specified .
#include <opencv2/core.hpp>
#include <opencv2/sfm.hpp>
#include <opencv2/viz.hpp>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
using namespace cv;
using namespace cv::sfm;
static void help() {
cout
<< "\n------------------------------------------------------------\n"
<< " This program shows the camera trajectory reconstruction capabilities\n"
<< " in the OpenCV Structure From Motion (SFM) module.\n"
<< " \n"
<< " Usage:\n"
<< " example_sfm_trajectory_reconstruction <path_to_tracks_file> <f> <cx> <cy>\n"
<< " where: is the tracks file absolute path into your system. \n"
<< " \n"
<< " The file must have the following format: \n"
<< " row1 : x1 y1 x2 y2 ... x36 y36 for track 1\n"
<< " row2 : x1 y1 x2 y2 ... x36 y36 for track 2\n"
<< " etc\n"
<< " \n"
<< " i.e. a row gives the 2D measured position of a point as it is tracked\n"
<< " through frames 1 to 36. If there is no match found in a view then x\n"
<< " and y are -1.\n"
<< " \n"
<< " Each row corresponds to a different point.\n"
<< " \n"
<< " f is the focal lenght in pixels. \n"
<< " cx is the image principal point x coordinates in pixels. \n"
<< " cy is the image principal point y coordinates in pixels. \n"
<< "------------------------------------------------------------------\n\n"
<< endl;
}
/* Build the following structure data
*
* frame1 frame2 frameN
* track1 | (x11,y11) | -> | (x12,y12) | -> | (x1N,y1N) |
* track2 | (x21,y11) | -> | (x22,y22) | -> | (x2N,y2N) |
* trackN | (xN1,yN1) | -> | (xN2,yN2) | -> | (xNN,yNN) |
*
*
* In case a marker (x,y) does not appear in a frame its
* values will be (-1,-1).
*/
void
parser_2D_tracks(const string &_filename, std::vector<Mat> &points2d )
{
ifstream myfile(_filename.c_str());
if (!myfile.is_open())
{
cout << "Unable to read file: " << _filename << endl;
exit(0);
} else {
double x, y;
string line_str;
int n_frames = 0, n_tracks = 0;
// extract data from text file
vector<vector<Vec2d> > tracks;
for ( ; getline(myfile,line_str); ++n_tracks)
{
istringstream line(line_str);
vector<Vec2d> track;
for ( n_frames = 0; line >> x >> y; ++n_frames)
{
if ( x > 0 && y > 0)
track.push_back(Vec2d(x,y));
else
track.push_back(Vec2d(-1));
}
tracks.push_back(track);
}
// embed data in reconstruction api format
for (int i = 0; i < n_frames; ++i)
{
Mat_<double> frame(2, n_tracks);
for (int j = 0; j < n_tracks; ++j)
{
frame(0,j) = tracks[j][i][0];
frame(1,j) = tracks[j][i][1];
}
points2d.push_back(Mat(frame));
}
myfile.close();
}
}
/* Keyboard callback to control 3D visualization
*/
bool camera_pov = false;
void keyboard_callback(const viz::KeyboardEvent &event, void* cookie)
{
if ( event.action == 0 &&!event.symbol.compare("s") )
camera_pov = !camera_pov;
}
/* Sample main code
*/
int main(int argc, char** argv)
{
// Read input parameters
if ( argc != 5 )
{
help();
exit(0);
}
// Read 2D points from text file
std::vector<Mat> points2d;
parser_2D_tracks( argv[1], points2d );
// Set the camera calibration matrix
const double f = atof(argv[2]),
cx = atof(argv[3]), cy = atof(argv[4]);
Matx33d K = Matx33d( f, 0, cx,
0, f, cy,
0, 0, 1);
bool is_projective = true;
vector<Mat> Rs_est, ts_est, points3d_estimated;
reconstruct(points2d, Rs_est, ts_est, K, points3d_estimated, is_projective);
// Print output
cout << "\n----------------------------\n" << endl;
cout << "Reconstruction: " << endl;
cout << "============================" << endl;
cout << "Estimated 3D points: " << points3d_estimated.size() << endl;
cout << "Estimated cameras: " << Rs_est.size() << endl;
cout << "Refined intrinsics: " << endl << K << endl << endl;
cout << "3D Visualization: " << endl;
cout << "============================" << endl;
viz::Viz3d window_est("Estimation Coordinate Frame");
window_est.setBackgroundColor(); // black by default
window_est.registerKeyboardCallback(&keyboard_callback);
// Create the pointcloud
cout << "Recovering points ... ";
// recover estimated points3d
vector<Vec3f> point_cloud_est;
for (int i = 0; i < points3d_estimated.size(); ++i)
point_cloud_est.push_back(Vec3f(points3d_estimated[i]));
cout << "[DONE]" << endl;
cout << "Recovering cameras ... ";
vector<Affine3d> path_est;
for (size_t i = 0; i < Rs_est.size(); ++i)
path_est.push_back(Affine3d(Rs_est[i],ts_est[i]));
cout << "[DONE]" << endl;
cout << "Rendering Trajectory ... ";
cout << endl << "Press: " << endl;
cout << " 's' to switch the camera pov" << endl;
cout << " 'q' to close the windows " << endl;
if ( path_est.size() > 0 )
{
// animated trajectory
int idx = 0, forw = -1, n = static_cast<int>(path_est.size());
while(!window_est.wasStopped())
{
for (size_t i = 0; i < point_cloud_est.size(); ++i)
{
Vec3d point = point_cloud_est[i];
Affine3d point_pose(Mat::eye(3,3,CV_64F), point);
char buffer[50];
sprintf (buffer, "%d", static_cast<int>(i));
viz::WCube cube_widget(Point3f(0.1,0.1,0.0), Point3f(0.0,0.0,-0.1), true, viz::Color::blue());
cube_widget.setRenderingProperty(viz::LINE_WIDTH, 2.0);
window_est.showWidget("Cube"+string(buffer), cube_widget, point_pose);
}
Affine3d cam_pose = path_est[idx];
viz::WCameraPosition cpw(0.25); // Coordinate axes
viz::WCameraPosition cpw_frustum(K, 0.3, viz::Color::yellow()); // Camera frustum
if ( camera_pov )
window_est.setViewerPose(cam_pose);
else
{
// render complete trajectory
window_est.showWidget("cameras_frames_and_lines_est", viz::WTrajectory(path_est, viz::WTrajectory::PATH, 1.0, viz::Color::green()));
window_est.showWidget("CPW", cpw, cam_pose);
window_est.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose);
}
// update trajectory index (spring effect)
forw *= (idx==n || idx==0) ? -1: 1; idx += forw;
// frame rate 1s
window_est.spinOnce(1, true);
window_est.removeAllWidgets();
}
}
return 0;
}
I would be really grateful if someone can help me through this. Thank you.

segmentation failed (core dumped) working with opencv

I'm running into a problem, trying to perform a template matching using OpenCV on Ubuntu 18.04LTS
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
int match_method =5;
string image_window = "Source Image";
string result_window = "Result window";
Mat img, templ, result;
/// Load image and template
img = imread("./RI2.jpg", IMREAD_GRAYSCALE );
templ = imread("./Pump2.jpg", IMREAD_GRAYSCALE );
/// Create windows
//namedWindow( image_window, WINDOW_AUTOSIZE );
//namedWindow( result_window, WINDOW_AUTOSIZE );
/// Source image to display
Mat img_display;
img.copyTo( img_display );
/// Create the result matrix
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
result.create( result_rows, result_cols, CV_32FC1 );
/// Do the Matching and Normalize
matchTemplate( img, templ, result, match_method );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
Mat resultgrey(result_rows, result_cols, CV_8UC1);
cout << "resultgrey.size().width: " << resultgrey.size().width << endl;
cout << "resultgrey.size().height: " << resultgrey.size().height << endl;
cout << "result.size().width: " << result.size().width << endl;
cout << "result.size().height: " << result.size().height << endl;
if( match_method == 0 || match_method == 1 )
{
for (int i=0; i<result.size().width; i++)
{
for (int j=0; j<result.size().height; j++)
{
if (result.at<float>(i,j)>=0.1)
{
resultgrey.at<int>(i,j)=0;
}
else
{
resultgrey.at<int>(i,j)=1;
}
}
}
}
else
{
for (int i=0; i<result.size().width; i++)
{
for (int j=0; j<result.size().height; j++)
{
if (result.at<float>(i,j)<=0.98)
{
resultgrey.at<int>(i,j)=0;
//cout << "0" << endl;
}
else
{
resultgrey.at<int>(i,j)=1;
//cout << "1" << endl;
}
}
}
}
cout << "3" << endl;
/// Localizing the objects
vector<Point> matchLoclist;
//cout << resultgrey << endl;
findNonZero(resultgrey, matchLoclist);
cout << "4" << endl;
if (matchLoclist.size() == 0)
{
cout << "no matches found" << endl;
return 0;
}
///Draw Rectangles on Pumps found in the scene
for (int i=0; i<matchLoclist.size(); i++)
{
//cout << "matchLoclist[i].x: "<<matchLoclist[i].x << endl << "matchLoclist[i].y: " << matchLoclist[i].y << endl;
rectangle( img_display, matchLoclist[i], Point( matchLoclist[i].x + templ.cols, matchLoclist[i].y + templ.rows ), Scalar::all(0), 2, 8, 0 );
rectangle( result, matchLoclist[i], Point( matchLoclist[i].x + templ.cols, matchLoclist[i].y + templ.rows ), Scalar::all(0), 2, 8, 0 );
}
imshow( image_window, img_display );
imshow( result_window, result );
waitKey(0);
return 0;
}
as an output i get:
xxx#ubuntu:~/Projects/Template_matching$ ./template_matching
resultgrey.size().width: 1216
resultgrey.size().height: 723
result.size().width: 1216
result.size().height: 723
Segmentation fault (core dumped)
This happens during the double for-loop where either a 1 or a 0 gets written into "resultrgrey" as I never get the "3" as an output from the cout below
if I take different input pictures (espacially smaller ones) the programm tends to run without this error.
I appreciate any help or suggestions!
Alex
You write outside of the allocated buffer because of (1) incorrectly specified data types and (2) swapped arguments to .at, as #rafix07 has noted.
You create 8-bit matrix (8 in CV_8UC1):
Mat resultgrey(result_rows, result_cols, CV_8UC1);
but try to assign 32-bit values to its elements in double-for loop:
resultgrey.at<int>(i,j)=0;
Template method cv::Mat::at calculates address of the (i,j)-th element in memory, based on:
data type, specified in template instantiation,
pointer to data start, stored in the cv::Mat instance,
and data stride (distance in bytes between leftmost pixels of two consecutive lines), also stored in the cv::Mat instance.
Then it returns reference to it. No checks is performed, for speed, therefore it's your responsibility to submit correct arguments.
Size of int is 32 bits on most modern platforms, but can be differrent.
Generally, it is safer to use types from stdint.h header, that have explicit length and sign in their names: uint8_t, int32_t, etc
Look at reference about Mat::at method
const _Tp& cv::Mat::at ( int i0, int i1 ) const
Parameters
i0 Index along the dimension 0
i1 Index along the dimension 1
the first dimenstion is number of rows, the second dim is number of columns, so you should change all lines in your code with at
resultgrey.at<int>(i,j) // i means col, j means row
to
resultgrey.at<int>(j,i)

Putting multiple video feed next to each other with OpenCV

I have real-time video from 3 different cameras, I would like to resize and then put the videos next to each other and fit them on one screen, basically:
-------------------------------------
| CAM LEFT | CAM MIDDLE | CAM RIGHT |
-------------------------------------
I have written the following code but for whatever reason I only have image on the LEFT side only. The middle and right side are replaced by a gray color background (I have no idea where that comes from). I have printed out all the coordinates and they look fine to me, with a total screen size of 1440 x 540 (I want the picture in the middle to be bigger).
- LEFT: 0,0,380,540
- MIDDLE: 380,0,680,540
- RIGHT: 1060,0,380,540
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/stitching.hpp"
#include <opencv2/opencv.hpp>
#include <opencv2/imgcodecs.hpp>
#include<iostream>
#include <fstream>
#include<conio.h> // may have to modify this line if not using Windows
int main(int argc, char **argv) {
int combinedScreenWidth = 1440;
int combinedScreenHeight = 540;
int rearCameraBiggerByThis = 100;
int combinedScreenWidthHalv = combinedScreenWidth / 3;
//initialize and allocate memory to load the video stream from camera
cv::VideoCapture cameraRight(0); // RIGHT CAM
cv::VideoCapture cameraMiddle(3); // REAR CAM
cv::VideoCapture cameraLeft(2); // LEFT CAM
if (!cameraRight.isOpened()) return 1;
if (!cameraMiddle.isOpened()) return 1;
if (!cameraLeft.isOpened()) return 1;
cv::Mat3b cameraRightFrame;
cv::Mat3b cameraMiddleFrame;
cv::Mat3b cameraLeftFrame;
cv::Mat3b cameraRightFrameMirrored;
cv::Mat3b cameraMiddleFrameMirrored;
cv::Mat3b cameraLeftFrameMirrored;
cv::Size camRightSize;
cv::Size camMiddleSize;
cv::Size camLeftSize;
cv::Mat3b cameraRightFrameMirroredResize;
cv::Mat3b cameraMiddleFrameMirroredResize;
cv::Mat3b cameraLeftFrameMirroredResize;
while (true) {
// Grab
cameraRight >> cameraRightFrame;
cameraMiddle >> cameraMiddleFrame;
cameraLeft >> cameraLeftFrame;
// Mirror
cv::flip(cameraRightFrame, cameraRightFrameMirrored, 1);
cv::flip(cameraMiddleFrame, cameraMiddleFrameMirrored, 1);
cv::flip(cameraLeftFrame, cameraLeftFrameMirrored, 1);
// Resize
camRightSize = cameraRightFrame.size();
camMiddleSize = cameraMiddleFrame.size();
camLeftSize = cameraLeftFrame.size();
std::cout << "----------------------> original camRightSize " << camRightSize.width << "x" << camRightSize.height << std::endl;
std::cout << "----------------------> original camMiddletSize " << camMiddleSize.width << "x" << camMiddleSize.height << std::endl;
std::cout << "----------------------> original camLeftSize " << camLeftSize.width << "x" << camLeftSize.height << std::endl;
resize(cameraRightFrameMirrored, cameraRightFrameMirroredResize, cv::Size(combinedScreenWidthHalv - rearCameraBiggerByThis, combinedScreenHeight));
resize(cameraMiddleFrameMirrored, cameraMiddleFrameMirroredResize, cv::Size(combinedScreenWidthHalv + 2 * rearCameraBiggerByThis, combinedScreenHeight));
resize(cameraLeftFrameMirrored, cameraLeftFrameMirroredResize, cv::Size(combinedScreenWidthHalv - rearCameraBiggerByThis, combinedScreenHeight));
camRightSize = cameraRightFrameMirroredResize.size();
camMiddleSize = cameraMiddleFrameMirroredResize.size();
camLeftSize = cameraLeftFrameMirroredResize.size();
std::cout << "----------------------> resized camRightSize " << camRightSize.width << "x" << camRightSize.height << std::endl;
std::cout << "----------------------> resized camMiddletSize " << camMiddleSize.width << "x" << camMiddleSize.height << std::endl;
std::cout << "----------------------> resized camLeftSize " << camLeftSize.width << "x" << camLeftSize.height << std::endl;
// Compilation
cv::Mat3b combinedFrame(camRightSize.height, camLeftSize.width + camMiddleSize.width + camRightSize.width);
// LEFT
std::cout << "LEFT: 0,0," << camLeftSize.width << "," << camLeftSize.height << std::endl;
cv::Mat3b leftSideOfScreen(combinedFrame, cv::Rect(0, 0, camLeftSize.width, camLeftSize.height));
cameraLeftFrameMirroredResize.copyTo(leftSideOfScreen);
// MIDDLE
std::cout << "MIDDLE: " << camLeftSize.width << ",0," << camMiddleSize.width << "," << camMiddleSize.height << std::endl;
cv::Mat3b middleSideOfScreen(combinedFrame, cv::Rect(camLeftSize.width, 0, camMiddleSize.width, camMiddleSize.height));
cameraRightFrameMirroredResize.copyTo(middleSideOfScreen);
// RIGHT
std::cout << "RIGHT: " << camLeftSize.width + camMiddleSize.width << ",0," << camRightSize.width << "," << camRightSize.height << std::endl;
cv::Mat3b rightSideOfScreen(combinedFrame, cv::Rect(camLeftSize.width + camMiddleSize.width, 0, camRightSize.width, camRightSize.height));
cameraMiddleFrameMirroredResize.copyTo(rightSideOfScreen);
// declare windows
cv::namedWindow("Combined", CV_WINDOW_NORMAL);
cv::setWindowProperty("Combined", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
cv::putText(combinedFrame, "LEFT", cv::Point(250, 50), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 255, 255), 2);
cv::putText(combinedFrame, "REAR", cv::Point(650, 50), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 255, 255), 2);
cv::putText(combinedFrame, "RIGHT", cv::Point(1050, 50), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 255, 255), 2);
cv::imshow("Combined", combinedFrame); // 1440 x 540 Screen size
//cv::imshow("Right Cam", cameraRightFrame);
//cv::imshow("Middle Cam", cameraMiddleFrame);
//cv::imshow("Left Cam", cameraLeftFrame);
//wait for 40 milliseconds
int c = cvWaitKey(1);
//exit the loop if user press "Esc" key (ASCII value of "Esc" is 27)
if (27 == char(c)) {
break;
}
}
return 0;
}

Decode QR code, from low quality image (with ZBar)

I tried to decode QR codes from images like this:
Based on the following code,
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <zbar.h>
#include <iostream>
using namespace cv;
using namespace std;
using namespace zbar;
//g++ main.cpp /usr/local/include/ /usr/local/lib/ -lopencv_highgui.2.4.8 -lopencv_core.2.4.8
int main(int argc, char* argv[])
{
VideoCapture cap(0); // open the video camera no. 0
// cap.set(CV_CAP_PROP_FRAME_WIDTH,800);
// cap.set(CV_CAP_PROP_FRAME_HEIGHT,640);
if (!cap.isOpened()) // if not success, exit program
{
cout << "Cannot open the video cam" << endl;
return -1;
}
ImageScanner scanner;
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video
cout << "Frame size : " << dWidth << " x " << dHeight << endl;
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
break;
}
Mat grey;
cvtColor(frame,grey,CV_BGR2GRAY);
int width = frame.cols;
int height = frame.rows;
uchar *raw = (uchar *)grey.data;
// wrap image data
Image image(width, height, "Y800", raw, width * height);
// scan the image for barcodes
int n = scanner.scan(image);
// extract results
for(Image::SymbolIterator symbol = image.symbol_begin();
symbol != image.symbol_end();
++symbol) {
vector<Point> vp;
// do something useful with results
cout << "decoded " << symbol->get_type_name() << " symbol \"" << symbol->get_data() << '"' <<" "<< endl;
int n = symbol->get_location_size();
for(int i=0;i<n;i++){
vp.push_back(Point(symbol->get_location_x(i),symbol->get_location_y(i)));
}
RotatedRect r = minAreaRect(vp);
Point2f pts[4];
r.points(pts);
for(int i=0;i<4;i++){
line(frame,pts[i],pts[(i+1)%4],Scalar(255,0,0),3);
}
//cout<<"Angle: "<<r.angle<<endl;
}
imshow("MyVideo", frame); //show the frame in "MyVideo" window
if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}
The naive ZLib approach fails 100%. But the zxing barcode scanner app can decode it from the computer screen, so it's definitely contains all the necessary information.
Any idea how to make the scanning more robust?

Failed Assertion Using HOGDescriptor

Ok, so I've decided that using a histogram of oriented gradients is a better method for image fingerprinting vs. creating a histogram of sobel derivatives. I think I finally have it mostly figured out but when I test my code I get the following:
OpenCV Error: Assertion failed ((winSize.width - blockSize.width) % blockStride.width == 0 && (winSize.height - blockSize.height) % blockStride.height == 0).
As of now I'm just trying to figure out how to compute the HOG correctly and see the results; but not visually, I just want some very basic output to see if the HOG was created. Then I'll figure out how to use it in image comparison.
Here is my sample code:
using namespace cv;
using namespace std;
int main(int argc, const char * argv[])
{
// Initialize string variables.
string thePath, img, hogSaveFile;
thePath = "/Users/Mikie/Documents/Xcode/images/";
img = thePath + "HDimage.jpg";
hogSaveFile = thePath + "HDimage.yml";
// Create mats.
Mat src;
// Load image as grayscale.
src = imread(img, CV_LOAD_IMAGE_GRAYSCALE);
// Verify source loaded.
if(src.empty()){
cout << "No image data. \n ";
return -1;
}else{
cout << "Image loaded. \n" << "Size: " << src.cols << " X " << src.rows << "." << "\n";
}
// Initialize float variables.
float imgWidth, imgHeight, newWidth, newHeight;
imgWidth = src.cols;
imgHeight = src.rows;
newWidth = 320;
newHeight = (imgHeight/imgWidth)*newWidth;
Mat dst = Mat::zeros(newHeight, newWidth, CV_8UC3);
resize(src, dst, Size(newWidth, newHeight), CV_INTER_LINEAR);
// Was resize successful?
if (dst.rows < src.rows && dst.cols < src.cols) {
cout << "Resize successful. \n" << "New size: " << dst.cols << " X " << dst.rows << "." << "\n";
} else {
cout << "Resize failed. \n";
return -1;
}
vector<float>theHOG(Mat dst);{
if (dst.empty()) {
cout << "Image lost. \n";
} else {
cout << "Setting up HOG. \n";
}
imshow("Image", dst);
bool gammaC = true;
int nlevels = HOGDescriptor::DEFAULT_NLEVELS;
Size winS(newWidth, newHeight);
// int block_size = 16;
// int block_stride= 8;
// int cell_size = 8;
int gbins = 9;
vector<float> descriptorsValues;
vector<Point> locations;
HOGDescriptor hog(Size(320, 412), Size(16, 16), Size(8, 8), Size(8, 8), gbins, -1, HOGDescriptor::L2Hys, 0.2, gammaC, nlevels);
hog.compute(dst, descriptorsValues, Size(0,0), Size(0,0), locations);
printf("descriptorsValues.size() = %ld \n", descriptorsValues.size()); //prints 960
for (int i = 0; i <descriptorsValues.size(); i++) {
cout << descriptorsValues[i] << endl;
}
}
cvWaitKey(0);
return 0;
}
As you can see, I messed around with different variables to define the sizes but to no avail so, I commented them out and tried manually setting them. Still nothing. What am I doing wrong? Any help will be greatly appreciated.
Thank you!
You are initializing the HOGDescriptor incorrectly.
The assertion states that each of the first three input parameters must satisfy the constraint:
(winSize - blockSize) % blockStride == 0
in both height and width dimensions.
The problem is that winSize.height does not satisfy this constraint, considering the other parameters you initialize hog with:
(412 - 16) % 8 = 4 //Problem!!
Probably the simplest fix is to increase your window dimensions from cv::Size(320,412) to something divisible by 8, perhaps cv::Size(320,416), but the specific size will depend on your specific requirements. Just pay attention to what the assertion is saying!

Resources