I am trying to run the ezsift library example. The example has name "image_match.cpp".
Here is the code
image_match.cpp
#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "../ezsift.h"
using namespace std;
#define USE_FIX_FILENAME 0
int main(int argc, char ** argv)
{
#if USE_FIX_FILENAME
char * file1 = "img1.pgm";
char * file2 = "img2.pgm";
#else
if (argc != 3)
{
printf("Please input two image filenames.\n");
printf("usage: image_match img1 img2\n");
return -1;
}
char file1[255];
char file2[255];
memcpy(file1, argv[1], sizeof(char) * strlen(argv[1]));
file1[strlen(argv[1])] = 0;
memcpy(file2, argv[2], sizeof(char) * strlen(argv[2]));
file2[strlen(argv[2])] = 0;
#endif
// Read two input images
ImageObj<uchar> image1, image2;
if(image1.read_pgm(file1) != 0)
{
printf("Failed to open input image1!\n");
return -1;
}
if(image2.read_pgm(file2) != 0)
{
printf("Failed to open input image2!\n");
return -1;
}
printf("Image 1 loaded. Image size: %d x %d\n", image1.w, image1.h);
printf("Image 2 loaded. Image size: %d x %d\n", image2.w, image2.h);
// Double the original image as the first octive.
double_original_image(true);
// Detect keypoints
list<SiftKeypoint> kpt_list1, kpt_list2;
printf("\nSIFT detection on image 1 ...\n");
sift_cpu(image1, kpt_list1, true);
printf("# keypoints in image1: %d\n", kpt_list1.size());
printf("\nSIFT detection on image 2 ...\n");
sift_cpu(image2, kpt_list2, true);
printf("# keypoints in image2: %d\n", kpt_list2.size());
// Save keypoint list, and draw keypoints on images.
char filename[255];
sprintf(filename, "s_A_keypoints.ppm");
draw_keypoints_to_ppm_file(filename, image1, kpt_list1);
export_kpt_list_to_file("s_A_keypoints.key", kpt_list1, true);
sprintf(filename, "s_B_keypoints.ppm");
draw_keypoints_to_ppm_file(filename, image2, kpt_list2);
export_kpt_list_to_file("s_B_keypoints.key", kpt_list2, true);
// Match keypoints.
list<MatchPair> match_list;
match_keypoints(kpt_list1, kpt_list2, match_list);
// Draw result image.
sprintf(filename, "s_A_B_matching.ppm");
draw_match_lines_to_ppm_file(filename, image1, image2, match_list);
printf("# of matched keypoints: %d\n", match_list.size());
return 0;
}
ezsift.h
#ifndef EZSIFT_H
#define EZSIFT_H
#include "util/image.h"
#include "util/img_io.h"
#include <vector>
#include <list>
.
.
.
#endif
#define DEGREE_OF_DESCRIPTORS (128)
// Enable doubling of original image.
void double_original_image(bool doubleFirstOctave);
// Detect keypoints and extract descriptor.
int sift_cpu(
const ImageObj<uchar> &image,
std::list<SiftKeypoint> & kpt_list,
bool bExtractDescriptors);
// Match keypoints from two keypoint lists.
int match_keypoints(
std::list<SiftKeypoint> & kpt_list1,
std::list<SiftKeypoint> & kpt_list2,
std::list<MatchPair> & match_list);
.
.
.
#endif
(I will not include all the code here, I just wanted to give an idea. It is ease to download the source and see the files that I am talking about)
Also there is a "ezsift.cpp" file with more files in the "util" folder
I'm trying to run it from the terminal. I go to the directory and type "gcc image_match.cpp" but is says that double_original_image, sift_cpu (and all other functions in the header file) are not defined.
more specifically is gives this error:
image_match.cpp:(.text+0x1c7): undefined reference to `double_original_image(bool)'
image_match.cpp:(.text+0x20d): undefined reference to `sift_cpu(ImageObj<unsigned char> const&, std::list<_SiftKeypoint, std::allocator<_SiftKeypoint> >&, bool)'
(these are not the only error of course. It gives same error for all the functions)
I then tried "gcc ../ezsift.cpp image_match.cpp" but the same error.
What am I doing wrong?? I am running ubuntu 14.04.
(expending Cameron's comment into a tested answer)
You need to compile both ezsift.cpp and img_io.cpp with your program (image_match.cpp), while providing the location of the header files (-I\path\to\directory). Here is a working snippet, assuming you are in the examples directory:
g++ image_match.cpp ../ezsift.cpp ../util/img_io.cpp -I.. -o image_match
Related
I have created with GIMP a C-Source image dump like the following:
/* GIMP RGBA C-Source image dump (example.c) */
static const struct {
guint width;
guint height;
guint bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
guint8 pixel_data[304 * 98 * 2 + 1];
} example= {
304, 98, 2,
"\206\061\206\061..... }
Is there a way to read this in GIMP again in order to get back the original image? because it doesn't seem possible.
Or does it exist a tool that can do this back-conversion?
EDITED
Following some suggestion I tried to write a simple C programme to make the reverse coversion ending up with something very similar to another code found on internet but both dont work:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "imgs_press.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
int main(int argc, char** argv) {
int fd;
char *name = "orignal_img.pnm";
fd = open(name, O_WRONLY | O_CREAT, 0644);
if (fd == -1) {
perror("open failed");
exit(1);
}
if (dup2(fd, 1) == -1) {
perror("dup2 failed");
exit(1);
}
// file descriptor 1, i.e. stdout, now points to the file
// "helloworld" which is open for writing
// You can now use printf which writes specifically to stdout
printf("P2\n");
printf("%d %d\n", press_high.width, press_high.height);
for(int x=0; x<press_high.width * press_high.height * 2; x++) {
printf("%d ", press_high.pixel_data[x]);
}
}
As suggested by n-1-8e9-wheres-my-share-m, maybe I need to manipulate the pixels usign the correct decode, but I have no idea how to do that, does anybody have other suggestions?
The image I got is indeed distorted:
Updated Answer
If you want to decode the RGB565 and write a NetPBM format PNM file without using ImageMagick, you can do this:
#include <stdint.h> /* for uint8_t */
#include <stdio.h> /* for printf */
/* tell compiler what those GIMP types are */
typedef int guint;
typedef uint8_t guint8;
#include <YOURGIMPIMAGE>
int main(){
int w = gimp_image.width;
int h = gimp_image.height;
int i;
uint16_t* RGB565p = (uint16_t*)&(gimp_image.pixel_data);
/* Print P3 PNM header on stdout */
printf("P3\n%d %d\n255\n",w, h);
/* Print RGB pixels, ASCII, one RGB pixel per line */
for(i=0;i<w*h;i++){
uint16_t RGB565 = *RGB565p++;
uint8_t r = (RGB565 & 0xf800) >> 8;
uint8_t g = (RGB565 & 0x07e0) >> 3;
uint8_t b = (RGB565 & 0x001f) << 3;
printf("%d %d %d\n", r, g ,b);
}
}
Compile with:
clang example.c
And run with:
./a.out > result.pnm
I have not tested it too extensively beyond your sample image, so you may want to make a test image with some reds, greens, blues and shades of grey to ensure that all my bit-twiddling is correct.
Original Answer
The easiest way to get your image back would be... to let ImageMagick do it.
So, take your C file and add a main() to it that simply writes the 304x98x2 bytes starting at &(example.pixel_data) to stdout:
Compile it with something like:
clang example.c -o program # or with GCC
gcc example.c -o program
Then run it, writing to a file for ImageMagick with:
./program > image.bin
And tell ImageMagick its size, type and where it is and what you want as a result:
magick -size 304x98 RGB565:image.bin result.png
I did a quick, not-too-thorough test of the following code and it worked fine for an image I generated with GIMP. Note it doesn't handle alpha/transparency but that could be added if necessary. Save it as program.c:
#include <unistd.h> /* for write() */
#include <stdint.h> /* for uint8_t */
/* tell compiler what those GIMP types are */
typedef int guint;
typedef uint8_t guint8;
<PASTE YOUR GIMP FILE HERE>
int main(){
/* Work out how many bytes to write */
int nbytes = example.width * example.height * 2;
/* Write on stdout for redirection to a file - may need to reopen in binary mode if on Windows */
write(1, &(example.pixel_data), nbytes);
}
If I run this with the file you provided via Google Drive I get:
Hello I am a beginner of C language for microprocessors. I want to read a ''.bmp'' file in order to apply line detection on it. I have declared a function to read the image. This error occurs when compile button is pushed:
#include "esp_camera.h"
#include "Arduino.h"
#include "FS.h" // SD Card ESP32
#include "SD_MMC.h" // SD Card ESP32
#include "soc/soc.h" // Disable brownour problems
#include "soc/rtc_cntl_reg.h" // Disable brownour problems
#include "driver/rtc_io.h"
#include <EEPROM.h> // read and write from flash memory
#include <SPI.h>
void imageReader(const char *imgName,
int *height,
int *width,
int *bitdepth,
unsigned char *header,
unsigned char *_colortable,
unsigned char *buf
) // READ AN IMAGE
{
int i;
fs::FS &fs = SD_MMC; //
FILE *file;
file = fopen(imgName,"rb"); // read imgName file ( it is a picture in .bmp format )
if(!file){
Serial.printf("Unable to read image");
}
for(i=0 ; i<54 ; i++){
header[i]=getc(file);
}
*width = *(int * )& header[18]; // width information of the image
*height = *(int * )& header[22]; // height information of image
*bitdepth = *(int *)& header[28];
if(*bitdepth<=8){
fread(_colortable,sizeof(unsigned char),1024,file);
}
fread(buf,sizeof(unsigned char),( 1600 * 1200 ) ,file);
fclose();
}
It gives this error. too few arguments to function 'int fclose(FILE*)'
The fclose() function needs to know which file to close. You need to tell it that by supplying "file" as an argument. You want to use fclose(file).
I am new to C++ and i am getting error like
error: no matching function for call to 'FaceDetector::FaceDetector(std::__cxx11::string)'
FaceDetector fd(string(DEFAULT_CASCADE_PATH));
and i am attaching my code and error log how to fix this please guide me
#define DEFAULT_CASCADE_PATH "cascades/haarcascade_frontalface_default.xml"
#define ORIGINALS_LIST "obama_raw/list"
#define OUTPUT_DIR "obama_faces"
#define OUTPUT_LIST "list"
#define FACE_SIZE Size(150,150)
#include <cstdlib>
#include <fstream>
#include "cv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "FaceDetector.h"
using namespace std;
using namespace cv;
void read_input_list(const string &list_path, vector<Mat> &images) {
ifstream file(list_path.c_str());
string path;
while (getline(file, path)) {
images.push_back(imread(path));
}
}
int main(int argc, char** argv) {
FaceDetector fd(string(DEFAULT_CASCADE_PATH));
vector<Mat> raw_faces;
ofstream out_list(format("%s/%s", OUTPUT_DIR, OUTPUT_LIST).c_str());
read_input_list(string(ORIGINALS_LIST), raw_faces);
int img_c = 0; //images counter
//now detect the faces in each of the raw images:
for (vector<Mat>::const_iterator raw_img = raw_faces.begin() ; raw_img != raw_faces.end() ; raw_img++){
vector<Rect> faces;
//detect faces in the image (there should be only one):
fd.findFacesInImage(*raw_img, faces);
//cut each face and write to disk:
for (vector<Rect>::const_iterator face = faces.begin() ; face != faces.end() ; face++){
int edge_size = max(face->width, face->height);
Rect square(face->x, face->y, edge_size, edge_size);
Mat face_img = (*raw_img)(square);
//resize:
resize(face_img, face_img, FACE_SIZE);
//write to disk:
string face_path = format("%s/%d.jpg", OUTPUT_DIR, img_c++);
imwrite(face_path,face_img);
out_list << face_path << endl;
}
}
out_list.close();
return 0;
}
and i am attaching my error log.Please can any one help.
Thanks in advance
Error : https://i.stack.imgur.com/RZXXK.jpg
From GCC 5, A new ABI is enabled by default. In that new ABI, std::__cxx11 namesapce was introduced.
According to your error message, It seems that your program and OpenCV library you want to link with were build with different GCC version, which made incompatible binary.
For more information, you can read the following page:
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
So I have played around in OpenCV a bunch before and never run into this problem. I am implementing a MeanShift algorithm and trying to do it on video devices, images, and videos. Devices and images work; however, no matter what I try, when I run VideoCapture on my filename (whether setting it in the Constructor or using the VideoCapture::open() method, and whether local or with a full path) I always get stuck in my error check.
Thoughts? Ideas? code below. running in Visual Studio 2012
#include "opencv2\highgui\highgui.hpp"
#include "opencv2\core\core.hpp"
#include "opencv2\opencv.hpp"
#include "opencv2\video\video.hpp"
#include <string>
using cv::Mat;
using std::string;
enum Filetype{Image, Video};
int main(int argc, char* argv[])
{
string filename = "short_front.avi";// "C:\\Users\\Jonathan\\Videos\\short_front.mp4"; //"hallways.jpg";
Mat cv_image; //convert to unsigned char * with data
Mat filtImage_;
Mat segmImage_;
Mat whiteImage_;
cv::VideoCapture vid;
vid.open("C:/Users/Jonathan/Desktop/TestMeanShift/TestMeanShift/short_front.avi");
cv::waitKey(1000);
if ( !vid.isOpened() ){
throw "Error when reading vid";
cv::waitKey(0);
return -1;
}
// cv_image = cv::imread(filename);//, CV_LOAD_IMAGE_COLOR);
// if(! cv_image.data){
// std::cerr << "Image Failure: " << std::endl;
// system("pause");
// return -1;
// }
//Mat cv_image_gray;
//cv::cvtColor(cv_image,cv_image_gray,CV_RGB2GRAY);
for (;;)
{
vid >> cv_image;
if ( !cv_image.data)
continue;
cv::imshow("Input",cv_image); //add a normal window here to resizable
}
EDIT: This is a distinct problem from the one listed here because it deals with a specific corner case: VideoCapture and ImageCapture both work, only not VideoCapture with a file. When it doesn't work, the code runs properly, except that the "video" it creates is incomplete as it didn't open properly. Therefore, as the code above does not crash in compile time or run time, the only indicator is bad output (6KB video output file). If you are having issues not with the corner case I am describing but general issues with the above functions in OpenCV, the aforementioned link could help you.
I am doing a project on object detection in OpenCV using haar training. I have to mark, in an image, all the places where the object is present. So, I need a code which opens each image so that I can mark the regions.
Similar to the one here:
#include <opencv/cv.h>
#include <opencv/cvaux.h>
#include <opencv/highgui.h>
// for filelisting
#include <stdio.h>
#include <sys/io.h>
// for fileoutput
#include <string>
#include <fstream>
#include <sstream>
#include <dirent.h>
#include <sys/types.h>
using namespace std;
IplImage* image=0;
IplImage* image2=0;
//int start_roi=0;
int roi_x0=0;
int roi_y0=0;
int roi_x1=0;
int roi_y1=0;
int numOfRec=0;
int startDraw = 0;
char* window_name="<SPACE>add <B>save and load next <ESC>exit";
string IntToString(int num)
{
ostringstream myStream; //creates an ostringstream object
myStream << num << flush;
/*
* outputs the number into the string stream and then flushes
* the buffer (makes sure the output is put into the stream)
*/
return(myStream.str()); //returns the string form of the stringstream object
};
void on_mouse(int event,int x,int y,int flag, void *param)
{
if(event==CV_EVENT_LBUTTONDOWN)
{
if(!startDraw)
{
roi_x0=x;
roi_y0=y;
startDraw = 1;
} else {
roi_x1=x;
roi_y1=y;
startDraw = 0;
}
}
if(event==CV_EVENT_MOUSEMOVE && startDraw)
{
//redraw ROI selection
image2=cvCloneImage(image);
cvRectangle(image2,cvPoint(roi_x0,roi_y0),cvPoint(x,y),CV_RGB(255,0,255),1);
cvShowImage(window_name,image2);
cvReleaseImage(&image2);
}
}
int main(int argc, char** argv)
{
char iKey=0;
string strPrefix;
string strPostfix;
string input_directory;
string output_file;
if(argc != 3) {
fprintf(stderr, "%s output_info.txt raw/data/directory/\n", argv[0]);
return -1;
}
input_directory = argv[2];
output_file = argv[1];
/* Get a file listing of all files with in the input directory */
DIR *dir_p = opendir (input_directory.c_str());
struct dirent *dir_entry_p;
if(dir_p == NULL) {
fprintf(stderr, "Failed to open directory %s\n", input_directory.c_str());
return -1;
}
fprintf(stderr, "Object Marker: Input Directory: %s Output File: %s\n", input_directory.c_str(), output_file.c_str());
// init highgui
cvAddSearchPath(input_directory);
cvNamedWindow(window_name,1);
cvSetMouseCallback(window_name,on_mouse, NULL);
fprintf(stderr, "Opening directory...");
// init output of rectangles to the info file
ofstream output(output_file.c_str());
fprintf(stderr, "done.\n");
while((dir_entry_p = readdir(dir_p)) != NULL)
{
numOfRec=0;
if(strcmp(dir_entry_p->d_name, ""))
fprintf(stderr, "Examining file %s\n", dir_entry_p->d_name);
/* TODO: Assign postfix/prefix info */
strPostfix="";
//strPrefix=input_directory;
strPrefix=dir_entry_p->d_name;
//strPrefix+=bmp_file.name;
fprintf(stderr, "Loading image %s\n", strPrefix.c_str());
if((image=cvLoadImage(strPrefix.c_str(),1)) != 0)
{
// work on current image
do
{
cvShowImage(window_name,image);
// used cvWaitKey returns:
// <B>=66 save added rectangles and show next image
// <ESC>=27 exit program
// <Space>=32 add rectangle to current image
// any other key clears rectangle drawing only
iKey=cvWaitKey(0);
switch(iKey)
{
case 27:
cvReleaseImage(&image);
cvDestroyWindow(window_name);
return 0;
case 32:
numOfRec++;
printf(" %d. rect x=%d\ty=%d\tx2h=%d\ty2=%d\n",numOfRec,roi_x0,roi_y0,roi_x1,roi_y1);
//printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
// currently two draw directions possible:
// from top left to bottom right or vice versa
if(roi_x0<roi_x1 && roi_y0<roi_y1)
{
printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x0,roi_y0,roi_x1-roi_x0,roi_y1-roi_y0);
// append rectangle coord to previous line content
strPostfix+=" "+IntToString(roi_x0)+" "+IntToString(roi_y0)+" "+IntToString(roi_x1-roi_x0)+" "+IntToString(roi_y1-roi_y0);
}
else
//(roi_x0>roi_x1 && roi_y0>roi_y1)
{
printf(" hello line no 154\n");
printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
// append rectangle coord to previous line content
strPostfix+=" "+IntToString(roi_x1)+" "+IntToString(roi_y1)+" "+IntToString(roi_x0-roi_x1)+" "+IntToString (roi_y0-roi_y1);
}
break;
}
}
while(iKey!=66);
{
// save to info file as later used for HaarTraining:
// <rel_path>\bmp_file.name numOfRec x0 y0 width0 height0 x1 y1 width1 height1...
if(numOfRec>0 && iKey==66)
{
//append line
/* TODO: Store output information. */
output << strPrefix << " "<< numOfRec << strPostfix <<"\n";
cvReleaseImage(&image);
}
else
{
fprintf(stderr, "Failed to load image, %s\n", strPrefix.c_str());
}
}
}}
output.close();
cvDestroyWindow(window_name);
closedir(dir_p);
return 0;
}
I ran the above code using Visual Studio 10.
When I run the above code it is opening the command window loading all the images (a new named window is also getting opened but getting but it is not staying for me to select the region) and then closing.
When I ran it using start without debugging option in VS10 it is I could see this:
Examining file img (6).jpeg
Loading image img (6).jpeg
Examining file img (6).JPG
Loading image img (6).JPG
Examining file img (7).jpeg
Loading image img (7).jpeg
Examining file img (7).jpg
Loading image img (7).jpg
Examining file img (8).jpeg
Loading image img (8).jpeg
Examining file img (8).jpg
Loading image img (8).jpg
Examining file img (9).jpeg
Loading image img (9).jpeg
Examining file img (9).jpg
Loading image img (9).jpg
Examining file img 1.jpeg
Loading image img 1.jpeg
the object marker fails and cannot load the image
I think that it is skipping the:
if((image=cvLoadImage(strPrefix.c_str(),1)) != 0){.....}
part of the code
There are few currently available object marking tools for Haar training. I use the tool in this link. Its perfectly worked for me. If you want to build your own tool please follow this tutorial. Any way I think when it comes to Haar training, it is waste of time to develop tools to capture coordinates because there are currently available tools for those and it is not the main goal of Haar training. Because Haar training takes more time to train and create cascade XML file. So its better to focus on training.