I'm trying to simple load an image (TIFF) and display a pixel value.
If I open the image using ImageJ the values are 32-bit float. But opening the same image using opencv I get really strange float values, e.g. 4.2039e-44.
If I read the value of a specific pixel using "int" the presented value is correct. Below is the code I use to test. And here a link for the image: https://goo.gl/Wmv9xE.
Thanks in advance.
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
int main(int argc, char **argv) {
std::string imageFile = "image.tiff";
cv::Mat image;
image = cv::imread(imageFile, CV_LOAD_IMAGE_ANYDEPTH); // Read the file
if (!image.data) // Check for invalid input
{
std::cout << "Could not open or find the image: " << imageFile << std::endl;
return -1;
}
std::cout << "Image:" << image.rows << " x " << image.cols << " Channels: " << image.channels() << " Depth: " << image.depth() << std::endl;
std::cout << "Value at 0,0: " << image.at<float>(0,1)<< std::endl; // Strange Value
std::cout << "Value at 0,0: " << image.at<int>(0,1)<< std::endl; // Correct Value
return (EXIT_SUCCESS);
}
* Update *
Trying to move forward with the code, I decided to create a function to convert the data to "int" reading from the file.
As a temporary solution this worked, but I'm still looking for the reason why the data is being loaded wrong.
int main(int argc, char **argv) {
std::string imageFile = "/home/slepicka/XSConfig/image.tiff";
cv::Mat image = openImage(imageFile);
if (!image.data) // Check for invalid input
{
std::cout << "Could not open or find the image: " << imageFile << std::endl;
return -1;
}
std::cout << "Image:" << image.rows << " x " << image.cols << " Channels: " << image.channels() << " Depth: " << image.depth() << " Type: " << image.type() << std::endl;
std::cout << "Value at 0,0: " << image.at<int>(0,1)<< std::endl; // Correct Value
//std::cout << "Data: " << image << std::endl;
return (EXIT_SUCCESS);
}
cv::Mat openImage(std::string filename){
cv::Mat imageLoad = cv::imread(filename, CV_LOAD_IMAGE_ANYDEPTH);
if(imageLoad.type() == CV_32F){
return convertToInt(imageLoad);
}
return imageLoad;
}
cv::Mat convertToInt(cv::Mat source){
int r, c;
cv::Mat converted;
converted.create(source.rows, source.cols, CV_32SC1);
for (r=0; r<source.rows;r++) {
for (c=0; c<source.cols;c++) {
converted.at<int>(r, c) = source.at<int>(r, c);
}
}
return converted;
}
Related
i 'm trying to use filter2D function. There is no error when i use anchor point from -1 to 2 (e.g Point(1,-1), Point(0,0), Point(1,2)...). But when i try to input anchor point at bottom right of kernel matrix (Point(2,-2)) and i get error. Can u guys help me. Thank you.
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <opencv2/highgui/highgui_c.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char const* argv[])
{
float data1[4][4] = { 1,2,3,3,8,1,10,11,15,16,9,18,1,23,24,25 };
Mat input = Mat(4, 4, CV_32F, data1);
cout << "Original Matrix = " << endl << "" << input << endl << endl;
float data2[3][3] = { 9,8,7,6,5,4,3,2,1 };
Mat kernel = Mat(3, 3, CV_32F, data2);
cout << "Kernel = " << endl << "" << kernel << endl << endl;
Mat output;
Mat output1;
filter2D(input, output, input.depth(), kernel, Point(2,-2), 0, 0);
//filter2D(input, output1, input.depth(), kernel, Point(1,-1), 0, 0);
cout << "Output Matrix = " << endl << "" << output << endl << endl;
//cout << "Output Matrix1 = " << endl << "" << output1 << endl << endl;
waitKey(1);
cin.get();
return 0;
}
So my main goal is to read the pixel data of a given texture, so to test this, i've created a new texture with target access then drawn it red.
The problem is that when I access the pixel data, SDL_RenderReadPixels() says the pitch is 0, and all the pixel data is 0. Also when I try to draw the new texture, it comes out black.
SDL_Texture* tempChar = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 3, 5);
if (SDL_SetRenderTarget(renderer, tempChar) != 0) {
cout << "SDL_SetRenderTarget() Error! " << SDL_GetError() << endl;
} else {
cout << "SDL_SetRenderTarget() success" << endl;
}
if (SDL_RenderClear(renderer) != 0) {
cout << "SDL_RenderClear() Error! " << SDL_GetError() << endl;
} else {
cout << "SDL_RenderClear() success" << endl;
}
if (SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255) != 0) {
cout << "SDL_SetRenderDrawColor() Error! " << SDL_GetError() << endl;
} else {
cout << "SDL_SetRenderDrawColor() success" << endl;
}
if (SDL_RenderFillRect(renderer, NULL) != 0) {
cout << "SDL_RenderClear() Error! " << SDL_GetError() << endl;
} else {
cout << "SDL_RenderClear() success" << endl;
}
int w;
int h;
Uint32 format;
int access;
if (SDL_QueryTexture(tempChar, &format, &access, &w, &h) != 0) {
cout << "SDL_QueryTexture() ERROR : " << SDL_GetError() << endl;
} else {
cout << "SDL_QueryTexture() no error" << endl;
}
cout << "width is : " << w << " height is : " << h << endl;
if (access == SDL_TEXTUREACCESS_TARGET) {
cout << "TARGET" << endl;
}
if (format == SDL_PIXELFORMAT_RGBA8888) {
cout << "format is : SDL_PIXELFORMAT_RGBA8888" << endl;
}
void* readPixels = NULL;
int pitch;
if (SDL_RenderReadPixels(renderer, NULL, 0, readPixels, pitch) != 0) {//12 pitch, 3x4bytes
//an error occurred
cout << "SDL_RenderReadPixels() Error, text probably wont work... :-/\n" << SDL_GetError() << endl;
} else {
cout << "SDL_RenderReadPixels() success" << endl;
}
cout << "pitch returned : " << pitch << endl;
menuMouse = tempChar;
for (int i = 0; i < 5; i++) {
cout << "i is : " << i << endl;
char* rowStart = ((char*) readPixels) + i * pitch;
cout << "pix data is : " << int(rowStart) << endl;
}
For some reason you assume that SDL_RenderReadPixels allocates pixels array and returns resulting pitch; it does neither. Calling side passes pixels array big enough to hold data, and its correct pitch, e.g.:
Uint32 pixels[3*5];
int pitch = sizeof(Uint32)*3;
In C/C++, functions does not modify input parameters directly, unless parameter is a reference type (in C++), or value is modified indirectly through pointer, so if function takes int - it is clearly input parameter, not output. E.g. take a look at SDL_CreateWindowAndRenderer, which outputs window and renderer pointers and hence its parameter types are pointer-to-pointer.
I am studying 3d point cloud and I am using opencv surface matchig module But I have an error I cant understand
My code is :
#include "stdafx.h"
#include <iostream>
#include <vector>
#include "opencv2/core/utility.hpp"
#include "opencv2\opencv_modules.hpp"
#include "opencv2\surface_matching.hpp"
#include "opencv2\surface_matching\ppf_helpers.hpp"
using namespace std;
using namespace cv;
using namespace cv::ppf_match_3d;
static void help(const string& errorMessage)
{
cout << "Program init error : " << errorMessage << endl;
cout << "\nUsage : ppf_matching [input model file] [input scene file]" << endl;
cout << "\nPlease start again with new parameters" << endl;
}
int main(int argc, char** argv)
{
// welcome message
cout << "****************************************************" << endl;
cout << "* Surface Matching demonstration : demonstrates the use of surface matching"
" using point pair features." << endl;
cout << "* The sample loads a model and a scene, where the model lies in a different"
" pose than the training.\n* It then trains the model and searches for it in the"
" input scene. The detected poses are further refined by ICP\n* and printed to the "
" standard output." << endl;
cout << "****************************************************" << endl;
/* if (argc < 2)
{
help("Not enough input arguments");
exit(1);
}*/
/*#if (defined __x86_64__ || defined _M_X64)
cout << "Running on 64 bits" << endl;
#else
cout << "Running on 32 bits" << endl;
#endif
#ifdef _OPENMP
cout << "Running with OpenMP" << endl;
#else
cout << "Running without OpenMP and without TBB" << endl;
#endif*/
string modelFileName = "C://opencv_contrib-master//modules//surface_matching//samples//data//parasaurolophus_6700";
string sceneFileName = "C://opencv_contrib-master//modules//surface_matching//samples//data//parasaurolophus_low_normals2";
Mat pc = loadPLYSimple(modelFileName.c_str(), 1);
// Now train the model
cout << "Training..." << endl;
int64 tick1 = cv::getTickCount();
ppf_match_3d::PPF3DDetector detector(0.025, 0.05);
detector.trainModel(pc);
int64 tick2 = cv::getTickCount();
cout << endl << "Training complete in "
<< (double)(tick2 - tick1) / cv::getTickFrequency()
<< " sec" << endl << "Loading model..." << endl;
// Read the scene
Mat pcTest = loadPLYSimple(sceneFileName.c_str(), 1);
// Match the model to the scene and get the pose
cout << endl << "Starting matching..." << endl;
vector<Pose3DPtr> results;
tick1 = cv::getTickCount();
detector.match(pcTest, results, 1.0 / 40.0, 0.05);
tick2 = cv::getTickCount();
cout << endl << "PPF Elapsed Time "
<< (tick2 - tick1) / cv::getTickFrequency() << " sec" << endl;
// Get only first N results
int N = 2;
vector<Pose3DPtr> resultsSub(results.begin(), results.begin() + N);
// Create an instance of ICP
ICP icp(100, 0.005f, 2.5f, 8);
int64 t1 = cv::getTickCount();
// Register for all selected poses
cout << endl << "Performing ICP on " << N << " poses..." << endl;
icp.registerModelToScene(pc, pcTest, resultsSub);
int64 t2 = cv::getTickCount();
cout << endl << "ICP Elapsed Time "
<< (t2 - t1) / cv::getTickFrequency() << " sec" << endl;
cout << "Poses: " << endl;
// debug first five poses
for (size_t i = 0; i<resultsSub.size(); i++)
{
Pose3DPtr result = resultsSub[i];
cout << "Pose Result " << i << endl;
result->printPose();
if (i == 0)
{
Mat pct = transformPCPose(pc, result->pose);
writePLY(pct, "para6700PCTrans.ply");
}
}
return 0;
}
And my error :(when code was these line :
detector.trainModel(pc);
int64 tick2 = cv::getTickCount();
I get this error:
Use debug mode. Change Key type at t_hash_int.cpp source file by these lines
#if (defined x86_64 || defined _M_X64)
typedef uint64_t KeyType;
#else
typedef unsigned int KeyType;
#endif
Build again from the source
Check this issue: https://github.com/opencv/opencv_contrib/issues/170
It seems that you use the release mode to run the program.
I have meet this problem before. When I change to debug mode. Everything works well.
I'm trying to import facial landmark points from webcam or video
using dlib into a file . I can display all detected landmarks on the terminal
but it is only saving the first and second landmark ponits (x,y) into the
output file , and not saving all the detected landmarks into
the output file
#include <dlib/opencv.h>
#include <opencv2/highgui/highgui.hpp>
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
using namespace dlib;
using namespace std;
int main()
{
try
{
cv::VideoCapture cap(0);
if (!cap.isOpened())
{
cerr << "Unable to connect to camera" << endl;
return 1;
}
image_window win;
frontal_face_detector detector = get_frontal_face_detector();
shape_predictor pose_model;
deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model;
while(!win.is_closed())
{
// Grab a frame
cv::Mat temp;
cap >> temp;
cv_image<bgr_pixel> cimg(temp);
std::vector<rectangle> faces = detector(cimg);
std::vector<full_object_detection> shapes;
for (unsigned long i = 0; i < faces.size(); ++i)
{
full_object_detection shape = pose_model(cimg, faces[i]);
cout << "number of parts: "<< shape.num_parts() << endl;
cout << "pixel position of first part: " << shape.part(0) << endl;
cout << "pixel position of second part: " << shape.part(1) << endl;
shapes.push_back(pose_model(cimg, faces[i]));
const full_object_detection& d = shapes[0];
ofstream outputfile;
outputfile.open("data1.txt");
outputfile<< shape.part(0).x() << " " << shape.part(0).y() << endl;
outputfile<< shape.part(1).x() << " " << shape.part(1).y() << endl;
}
win.clear_overlay();
win.set_image(cimg);
win.add_overlay(render_face_detections(shapes));
}
}
catch(serialization_error& e)
{
cout << "You need dlib's default face landmarking model file to run this example." << endl;
cout << "You can get it from the following URL: " << endl;
cout << " http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
cout << endl << e.what() << endl;
}
catch(exception& e)
{
cout << e.what() << endl;
}
}
Am I wrong or you want to save all landmarks when you have only:
ofstream outputfile;
outputfile.open("data1.txt");
outputfile<< shape.part(0).x() << " " << shape.part(0).y() << endl;
outputfile<< shape.part(1).x() << " " << shape.part(1).y() << endl;
And even not closing the file correctly. Try with for statement.
I am using HOG descriptor for feature extraction. I am using visual studio 2012 and opencv 2.4.9 version. I am getting run time error in hog.compute function.
int main()
{
Mat img_raw = imread("p1.jpg", 1); // load as color image.
Mat img;
cvtColor(img_raw, img, CV_RGB2GRAY);
HOGDescriptor hog;
vector<float> descriptor;
vector<Point>locations;
hog.compute(img, descriptor,Size(32,32),Size(0,0),locations);
cout << "HOG descriptor size is " << hog.getDescriptorSize() << endl;
cout << "img dimensions: " << img.cols << " width x " << img.rows << "height" << endl;
cout << "Found " << descriptor.size() << " descriptor values" << endl;
cout << "Nr of locations specified : " << locations.size() << endl;
return 0;
}