Is there a function similar MATLAB's 'impixelinfo()' available in OpenCV? - c++

I'm searching for a function in OpenCV that is similar to impixelinfo() in MATLAB.
impixelinfo() shows you
the location of the pixel (x, y) and
the pixel intensity of your cursor hovering in the image,
like:
impixelinfo() in matlab shows you this
Is there any implementation of this in OpenCV already? Does anyone have a personal version of it created?

You can do something like this:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat img;
void
CallBackFunc(int event,int x,int y,int flags,void* userdata)
{
if(event==EVENT_MOUSEMOVE){
cout << "Pixel (" << x << ", " << y << "): " << img.at<Vec3b>(y,x) << endl;
}
}
int main()
{
// Read image from file
img=imread("demo.jpg");
// Check it loaded
if(img.empty())
{
cout << "Error loading the image" << endl;
exit(1);
}
//Create a window
namedWindow("ImageDisplay",1);
// Register a mouse callback
setMouseCallback("ImageDisplay",CallBackFunc,nullptr);
// Main loop
while(true){
imshow("ImageDisplay",img);
waitKey(50);
}
}
As a result of the helpful comments, I (hopefully) improved the code and now handle grayscale images, and have also set the RGB ordering more akin to how non-OpenCV aficionados might expect it - i.e. RGB rather than BGR. The updated function is below:
void
CallBackFunc(int event,int x,int y,int flags,void* userdata)
{
if(event==EVENT_MOUSEMOVE){
// Test if greyscale or color
if(img.channels()==1){
cout << "Grey Pixel (" << x << ", " << y << "): " << (int)img.at<uchar>(y,x) << endl;
} else {
cout << "RGB Pixel (" << x << ", " << y << "): " << (int)img.at<Vec3b>(y,x)[2] << "/" << (int)img.at<Vec3b>(y,x)[1] << "/" << (int)img.at<Vec3b>(y,x)[0] << endl;
}
}
}

Related

weird glm::mat2x4 assignment behaviour

I am trying to load freetype chars, stuff them into a texture as subimages and then render them instanced.
While most of it seems to work, right now I have a problem with storing the texture coordinates into a glm::mat2x4 matrix.
As can be seen below each character has a struct with information I right now deem necessary, including a matrix called face, which should store the texture coordinates.
But when it comes to assigning the coordinates, after leaving the loop in which it takes place, suddenly all the values go crazy, without any (wanted/ intended) operation taking place from my side.
After creating the texture atlas with freetype and putting all my structs into the map, I assign the width and height of my texture aw & ah to a storage class called c_atlas.
I calculate the texture coordinates in the loop shown below, make the glm::mat2x4 a 0.0f matrix and then stuff them into it. Couting them into the console gives the values I want.
After leaving the for loop I start another one, browsing over the matrix and cout them into the console, which gives me more or less random values in the range of e^-23 to e^32.
All of this happens in namespace foo and is called in a constructor of a class in the same namespace (sth. like this:)
foo::class::constructor()
{
call_function();
}
int main()
{
foo::class c;
c.call_function();
}
I crafted a minimum working example, but unfortunatly I am not able to replicate the error.
So I have the following loop running (a part of call_function():
namespace foo
{
namespace alphabet
{
const char path_arial[] = "res/font/consola.ttf";
class character
{
public:
glm::vec2 advance;
glm::vec2 bearing;
glm::vec2 size;
glm::vec2 offset;
glm::mat2x4 face;
};
std::map<char, character> char_map;
FT_Library m_ftlib;
FT_Face m_ftface;
GLuint m_VBO, m_VAO;
}
c_atlas ascii;
}
void foo::call_function()
{
//creating all the charactur structs with freetype and store them in the char_map
std::ofstream f("atlas_data.csv", std::ios::openmode::_S_app);
f << "letter;topleft.x;topleft.y;topright.x;topright.y;bottomright.x;bottomright.y;bottomleft.x;bottomleft.y" << std::endl;
for(auto c : alphabet::char_map)
{
std::cout << "b4: " << c.second.offset.x;
c.second.offset /= glm::vec2(aw,ah);
std::cout << "\nafter: " << c.second.offset.x << std::endl;
glm::vec2 ts = c.second.size/glm::vec2(aw,ah);
//couts the right values
uint16_t n = 0;
c.second.face = glm::mat2x4(0.0f);
for(uint16_t i = 0; i < 4; ++i)
{
std::cout << c.first << " at init:\n";
std::cout << c.second.face[0][i] << "\n";
std::cout << c.second.face[1][i] << std::endl;
}
//couts the right values
c.second.face[0][n++] = c.second.offset.x;
c.second.face[0][n++] = c.second.offset.y;
c.second.face[0][n++] = c.second.offset.x+ts.x;
c.second.face[0][n++] = c.second.offset.y;
n = 0;
c.second.face[1][n++]= c.second.offset.x+ts.x;
c.second.face[1][n++] = c.second.offset.y+ts.y;
c.second.face[1][n++] = c.second.offset.x;
c.second.face[1][n++]= c.second.offset.y+ts.y;
for(uint16_t i = 0; i < 4; ++i)
{
std::cout << c.first << " assigned:\n";
std::cout << c.second.face[0][i] << "\n";
std::cout << c.second.face[1][i] << std::endl;
}
//still couts the right values
f << (char)c.first << ";" << c.second.face[0].x << ";" << c.second.face[0].y << ";" << c.second.face[0].z << ";" << c.second.face[0].w << ";" << c.second.face[1].x << ";" << c.second.face[1].y << ";" << c.second.face[1].z << ";" << c.second.face[1].w << std::endl;
//the file also have the right values
}
f.close();
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
//yet here all the values totally off track, i.e. e^32 or e^-23 (while they should all be between 0.01f - 1.0f)
for(auto i : alphabet::char_map)
{
std::cout << "\ntopleft:\n";
std::cout << "X: " << i.second.face[0].x << " | " << "Y: " << i.second.face[0].x;
std::cout << "\ntopright:\n";
std::cout << "X: " << i.second.face[0].z << " | " << "Y: " << i.second.face[0].w;
std::cout << "\nbotleft:\n";
std::cout << "X: " << i.second.face[1].x << " | " << "Y: " << i.second.face[1].x;
std::cout << "\nbotright:\n";
std::cout << "X: " << i.second.face[1].z << " | " << "Y: " << i.second.face[1].w;
}
}
my mwe:
#include <iostream>
#include <string>
#include "glm/glm.hpp"
#include "GL/gl.h"
#include <map>
struct bin
{
glm::mat2x4 mat;
};
int main( int argc, char *argv[] )
{
std::map<char, bin> bucket;
uint16_t r = 0;
for(uint16_t n = 0; n < 7; ++n)
{
glm::vec4 v = glm::vec4(0.12128f, 0.12412f, 0.15532f, 0.23453f);
bin b;
r = 0;
b.mat[0][r++] = v.x;
b.mat[0][r++] = v.y;
b.mat[0][r++] = v.z;
b.mat[0][r++] = v.w;
r = 0;
b.mat[1][r++] = v.x;
b.mat[1][r++] = v.y;
b.mat[1][r++] = v.z;
b.mat[1][r++] = v.w;
bucket[n] = b;
}
for(auto it : bucket)
{
r = 0;
std::cout << "0:\t" << it.second.mat[0][0] << "\t" << it.second.mat[0][1] << "\t" << it.second.mat[0][2] << "\t" << it.second.mat[0][3] << "\n";
r = 0;
std::cout << "1:\t" << it.second.mat[1][0] << "\t" << it.second.mat[1][1] << "\t" << it.second.mat[1][2] << "\t" << it.second.mat[1][3] << std::endl;
}
return 0;
}
Right now I am totally lost, especially as my mwe works fine.
I am clueless what goes wrong after leaving the for-loop, so thanks for any thought on that!
Indeed, I could just rewrite that section and hope it would work - as my mwe does. But I would like to find out/ get help on finding out what exactly happens between the "assign" for loop and the "retrieve" for loop. Any ideas on that?
I made it work for me now:
Appartenly assigning the values this way:
for(auto c : alphabet::char_map)
{
c.second.face[0][n++] = c.second.offset.x;
//and so on
}
Did not work properly (for whatever reason..)
Changing this into a for(uint16_t i = 32; i < 128; ++i) worked for me. Also it was just the assigning loop, the auto-iterating ofer the map elsewhere works just fine.

QT frame visualisation

Currently started to work with qt and found some bug in my code, and I can't understand where it comes from. Maybe you will see and explain why it happens.
Here is main.cpp code part which changes shutter from 3000 to maximum:
if (camera.test_cam->liveFrameReady())
{
camera.visualizeFrame(camera.test_cam->liveFrame());
camera.set_shutter(0, 1, 3000 + i * 200);
controlWidget->update(camera.test_cam->liveFrame());
i++;
}
The code works slowly(1 fps ), because of the camera.visuzlizeFrame() method:
void OsCam::visualizeFrame(Common::FrameHandle hFrame)
{
void* buffer_ptr = this->getFrameData(hFrame);
int width = hFrame->dataType()->width();
int height = hFrame->dataType()->height();
cv::Mat m(height, width, CV_8UC3, (int*)buffer_ptr);
cv::imshow("test image", m);
cv::waitKey(1);
}
Gui interface shows the camera frame in real time, test image from visualizeFrame at the background
Actionally, I don't need to call this method (I used it just to be sure that I can read the memory and I used opencv because I am more familiar with it).
But if I get rid of this camera.visuzlizeFrame() my gui becomes white and does not give any response.
Even if I use cv::waitKey or Sleep functions, nothing happens to the gui.
void ControlWidget::update(Common::FrameHandle hFrame)
{
try
{
QImage img((uchar*)hFrame->buffer()->data(), hFrame->dataType()->width(), hFrame->dataType()->height(), QImage::Format::Format_RGB888);
QSize standart_size = QSize(hFrame->dataType()->width() / 3, hFrame->dataType()->height() / 3);
QPixmap rectPxmp = QPixmap::fromImage(img).scaled(standart_size);
this->camera_1->setPixmap(rectPxmp);
this->camera_2->setPixmap(rectPxmp);
cv::waitKey(300);
}
catch (GeneralException& e)
{
std::cout << e.what() << std::endl;
}
}
Shall I go to QThreads? One thread for reading the buffer and another one for visualization of gui?
Thank you!
some additional code:
void* OsCam::getFrameData(Common::FrameHandle hFrame)
{
bool displayFrameData = false;
void* pFrameData = NULL;
try
{
if (hFrame)
{
if (displayFrameData)
{
// display information about the frame
cout << "Frame index: " << hFrame->frameIndex();
cout << "Frame timestamp: " << hFrame->timestamp();
// display information about the frame "data type"
DataTypeHandle hDataType = hFrame->dataType();
cout << "Frame size in bytes: " << hDataType->frameSizeInBytes() << endl;
cout << "Width in pixels: " << DataType::width(hDataType) << endl;
cout << "Height in rows: " << DataType::height(hDataType) << endl;
cout << "Bit depth: " << DataType::bitDepth(hDataType) << endl;
cout << "Bytes/line (stride): " << DataType::stride(hDataType) << endl;
// display the frame video format
VideoDataType::Format videoFormat = VideoDataType::format(hDataType);
cout << "Video format: " << VideoDataType::formatString(videoFormat).c_str() << endl;
// get a pointer to the frame data
}
pFrameData = hFrame->buffer()->data();
}
}
catch (GeneralException& e)
{
cout << e.what() << endl;
}
return pFrameData;
}
and main (I changed it a little bit) :
int main(int argc, char **argv)
{
QApplication app(argc, argv);
ControlWidget *controlWidget = new ControlWidget;
//controlWidget->show();
try
{
OsCam camera;
int i = 0;
for (int j = 0; j<10000 ; j++)
{
if ((camera.test_cam->liveFrameReady()))
{
Common::FrameHandle loaded = camera.test_cam->liveFrame()->clone();
camera.visualizeFrame(loaded);
controlWidget->update(loaded);
camera.set_shutter(0, 1, 3000 + i * 200);
loaded->~Frame();
}
i++;
}
}
catch (GeneralException& e)
{
std::cout << e.what() << std::endl;
int a;
std::cin >> a;
return 1;
}
}
After cv::named_window

save() function in Armadillo

I'm using the Armadillo library in a C++ project (with Xcode) and I would like to create a .mat file containing matrix A (as in the code hereafter).
#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;
int main ()
{
mat A;
A << 0.165300 << 0.454037 << 0.995795 << 0.124098 << 0.047084 << endr
<< 0.688782 << 0.036549 << 0.552848 << 0.937664 << 0.866401 << endr
<< 0.348740 << 0.479388 << 0.506228 << 0.145673 << 0.491547 << endr
<< 0.148678 << 0.682258 << 0.571154 << 0.874724 << 0.444632 << endr
<< 0.245726 << 0.595218 << 0.409327 << 0.367827 << 0.385736 << endr;
cout << A << endl;
bool status = A.save("test.mat", arma_ascii);
if(status == true)
{
cout << "Save OK !" << endl << endl;
}
else
{
cout << "Problem with save" << endl << endl;
}
mat B;
B.load("test.mat", arma_ascii);
cout << B;
return 0;
}
Everything works fine, as you can see in the results below, except the fact that I cannot find the file "test.mat" anywhere :( ! It is supposed to be in the project's folder, but unfortunately this is not the case! Anyone have any idea to solve this issue?
0.1653 0.4540 0.9958 0.1241 0.0471
0.6888 0.0365 0.5528 0.9377 0.8664
0.3487 0.4794 0.5062 0.1457 0.4915
0.1487 0.6823 0.5712 0.8747 0.4446
0.2457 0.5952 0.4093 0.3678 0.3857
Save OK !
0.1653 0.4540 0.9958 0.1241 0.0471
0.6888 0.0365 0.5528 0.9377 0.8664
0.3487 0.4794 0.5062 0.1457 0.4915
0.1487 0.6823 0.5712 0.8747 0.4446
0.2457 0.5952 0.4093 0.3678 0.3857
Thanks in advance!
P.S. I have problems with the function load() too. It always fail to read the file located in the project's folder.

Weirdly behaving pixel by pixel 3d graphing program [Faster drawing by dragging the window]

So I was coding a simple 3d graphing program in C++ using Allegro 4 libraries. I made it in the most simple way, by drawing pixel by pixel. Usually, putting single pixels on the screen is pretty slow because of how Allegro works and to plot a graph in resolution of 640x480 I have to wait a minute or two.
So I was rendering an image for my buddy to show and so I was dragging windows around to have a good screenshot and I discovered that by dragging the window with the rendering picture, it greatly speeds up as long as I hold the window. From 2 minutes it draws everything in 10 seconds.
What's the cause of this bizzare behavior? Is it something related to Windows' windows or is it caused by Allegro itself? Is there any explanation for this?
Screenshot
Also my code
#include <allegro.h>
#include <iostream>
#include <math.h>
using namespace std;
float MAX_Z = 1;
float MIN_Z =-1;
float SCALE =50;
inline void init(unsigned int width, unsigned int height)
{
allegro_init();
set_color_depth(24);
set_gfx_mode(GFX_AUTODETECT_WINDOWED, width, height, 0, 0);
install_timer();
install_keyboard();
install_mouse();
}
inline void deinit()
{
clear_keybuf();
allegro_exit();
}
int get_z_color (float z)
{
if (z >= 0)
{
return makecol(255, (z/MAX_Z)*255, (z/MAX_Z)*255);
}
else
{
return makecol(255 - (z/MIN_Z)*255,0, 0);
}
}
float get_z (float x, float y)
{
return sin(sqrt(pow(x,2)+pow(y,2)));
}
float int_to_float (int a)
{
return a;
}
int main()
{
unsigned int res_width, res_height;
cout << "Window size (W,H): ";
cin >> res_width >> res_height;
cout << endl << "Initiating in " << res_width << "x" << res_height << " resolution..." << endl;
init(res_width,res_height);
cout << "Success! Drawing graph..." << endl;
for (int y=0; y<res_height; y++)
{
for (int x=0; x<res_width; x++)
{
float valued_x = (int_to_float(x)-(int_to_float(res_width)/2))/SCALE;
float valued_y = (int_to_float(-y)+(int_to_float(res_height)/2))/SCALE;
_putpixel24(screen,x,y,get_z_color(get_z(valued_x,valued_y)));
//cout << "Drawing (" << valued_x << "," << valued_y << ")" << endl;
}
}
cout << "Graph drawn." << endl;
cin >> new char;
cout << "Closing...";
deinit();
return 0;
}
END_OF_MAIN()
Drawing on screen surfaces, whatever library you're using, is always a costly operation.
I never used Allegro (I'm using the SDL), but I would guess that windows redraws the screen surface each time a single pixel is put on it, and by dragging the windows around, you prevent the redrawing from actually happening.
If you want your program to get a dramatic increase in performance, you should always draw to an off-screen surface, and blit the entire surface to the screen surface once the drawing is over (this is a basic double buffering technique).
Like I said, I never used Allegro, but from what I could gather, you could do something like that :
int main()
{
unsigned int res_width, res_height;
cout << "Window size (W,H): ";
cin >> res_width >> res_height;
cout << endl << "Initiating in " << res_width << "x" << res_height << " resolution..." << endl;
init(res_width,res_height);
BITMAP *temporaryBitmap = create_bitmap(res_width, res_height);
cout << "Success! Drawing graph..." << endl;
for (int y=0; y<res_height; y++)
{
for (int x=0; x<res_width; x++)
{
float valued_x = (int_to_float(x)-(int_to_float(res_width)/2))/SCALE;
float valued_y = (int_to_float(-y)+(int_to_float(res_height)/2))/SCALE;
_putpixel24(temporaryBitmap,x,y,get_z_color(get_z(valued_x,valued_y)));
//cout << "Drawing (" << valued_x << "," << valued_y << ")" << endl;
}
}
blit(temporaryBitmap, screen, 0, 0, 0, 0, temporaryBitmap->w, temporaryBitmap->h);
cout << "Graph drawn." << endl;
cin >> new char;
cout << "Closing...";
destroy_bitmap(temporaryBitmap);
deinit();
return 0;
}

How to get camera's parameters at PCL?

I installed PCL1.7.2. and I am trying use PCL libraries.
I want to show camera's parameters by "const", so, I want to get camera's parameters. But I don't understand how to get the camera's parameters.
I saw the "pcl::visualization::Camera Class Reference".
http://docs.pointclouds.org/trunk/classpcl_1_1visualization_1_1_camera.html
and I understood there are focal, pos, view etc on the "Camera" object.
and now I have confirmed that the following code run.
but I can't understand how to get Camera's member.
this is how to set Camera's member values.
viewer.setCameraPosition(pos_x, pos_y, pos_z, view_x, view_y, view_z, up_x, up_y, up_z, viewport);
so, someone please show me how to get Camera's parameters at the following code.
this is now roading source.
#include "stdafx.h"
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
int user_data=0;
void
viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{
viewer.setBackgroundColor(1.0, 0.5, 1.0);
pcl::PointXYZ o;
o.x = 1.0;
o.y = 0;
o.z = 0;
viewer.addSphere(o, 0.25, "sphere", 0);
std::cout << "i only run once" << std::endl;
}
void
viewerPsycho(pcl::visualization::PCLVisualizer& viewer)
{
static unsigned count = 0;
std::stringstream ss;
ss << "Once per viewer loop: " << count++;
viewer.removeShape("text", 0);
viewer.addText(ss.str(), 200, 300, "text", 0);
//FIXME: possible race condition here:
user_data++;
}
int _tmain(int argc, const _TCHAR** argv)
{
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::io::loadPCDFile("c:\\data\\triceratops\\raw_0.pcd", *cloud);
pcl::visualization::CloudViewer viewer("Cloud Viewer");
//blocks until the cloud is actually rendered
viewer.showCloud(cloud);
//use the following functions to get access to the underlying more advanced/powerful
//PCLVisualizer
//This will only get called once
viewer.runOnVisualizationThreadOnce(viewerOneOff);
//This will get called once per visualization iteration
viewer.runOnVisualizationThread(viewerPsycho);
while (!viewer.wasStopped())
{
//you can also do cool processing here
//FIXME: Note that this is running in a separate thread from viewerPsycho
//and you should guard against race conditions yourself...
user_data++;
}
return 0;
}
This should work:
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
std::vector<pcl::visualization::Camera> cam;
//Save the position of the camera
viewer->getCameras(cam);
//Print recorded points on the screen:
cout << "Cam: " << endl
<< " - pos: (" << cam[0].pos[0] << ", " << cam[0].pos[1] << ", " << cam[0].pos[2] << ")" << endl
<< " - view: (" << cam[0].view[0] << ", " << cam[0].view[1] << ", " << cam[0].view[2] << ")" << endl
<< " - focal: (" << cam[0].focal[0] << ", " << cam[0].focal[1] << ", " << cam[0].focal[2] << ")" << endl;