using opencv features2d on iPhone - iphone

I'm trying to use feature detection via OpenCV on iOS and I'm running into a conundrum:
features2d relies on highgui
highgui can't be built on iOS (or at least not that I can figure out).
This leads me to believe: features2d just can't be used on iOS without rewriting the module to remove the calls to cvSaveImage() and cvLoadImage(). Is this wrong? Anyone run into this and solved it?

You are taking the wrong aproach, you dont need highgui since that library is only ment to make it easier for you to handle the results of your processing, you can simply do those steps manually.
for example, consider this HOG example:
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
int
main(int argc, char *argv[])
{
const char *imagename = argc > 1 ? argv[1] : "../../image/pedestrian.png";
cv::Mat img = cv::imread(imagename, 1);
if(img.empty()) return -1;
cv::HOGDescriptor hog;
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
std::vector<cv::Rect> found;
// 画像,検出結果,閾値(SVMのhyper-planeとの距離),
// 探索窓の移動距離(Block移動距離の倍数),
// 画像外にはみ出た対象を探すためのpadding,
// 探索窓のスケール変化係数,グルーピング係数
hog.detectMultiScale(img, found, 0.2, cv::Size(8,8), cv::Size(16,16), 1.05, 2);
std::vector<cv::Rect>::const_iterator it = found.begin();
std::cout << "found:" << found.size() << std::endl;
for(; it!=found.end(); ++it) {
cv::Rect r = *it;
// 描画に際して,検出矩形を若干小さくする
r.x += cvRound(r.width*0.1);
r.width = cvRound(r.width*0.8);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
cv::rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
}
// 結果の描画
cv::namedWindow("result", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
cv::imshow( "result", img );
cv::waitKey(0);
}
it is made for a non iOS enviroment, however you can simply replace all highgui calls for
native iOS stuff.
You can get a very good image handling for opencv library from here:
http://aptogo.co.uk/2011/09/opencv-framework-for-ios/
so what you should really care about in that code is just this part:
cv::HOGDescriptor hog;
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
std::vector<cv::Rect> found;
// 画像,検出結果,閾値(SVMのhyper-planeとの距離),
// 探索窓の移動距離(Block移動距離の倍数),
// 画像外にはみ出た対象を探すためのpadding,
// 探索窓のスケール変化係数,グルーピング係数
hog.detectMultiScale(img, found, 0.2, cv::Size(8,8), cv::Size(16,16), 1.05, 2);
std::vector<cv::Rect>::const_iterator it = found.begin();
std::cout << "found:" << found.size() << std::endl;
for(; it!=found.end(); ++it) {
cv::Rect r = *it;
// 描画に際して,検出矩形を若干小さくする
r.x += cvRound(r.width*0.1);
r.width = cvRound(r.width*0.8);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
cv::rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
}
For a BRIEF:
// You get your img into a cv mat from the uiimage or whatever.
cv::Mat gray_img;
cv::cvtColor(img, gray_img, CV_BGR2GRAY);
cv::normalize(gray_img, gray_img, 0, 255, cv::NORM_MINMAX);
std::vector<cv::KeyPoint> keypoints;
std::vector<cv::KeyPoint>::iterator itk;
cv::Mat descriptors;
//
// threshold=0.05, edgeThreshold=10.0
cv::SiftFeatureDetector detector(0.05,10.0);
detector.detect(gray_img, keypoints);
// Brief に基づくディスクリプタ抽出器
cv::BriefDescriptorExtractor extractor;
cv::Scalar color(50,50,155);
extractor.compute(gray_img, keypoints, descriptors);
// 32次元の特徴量 x keypoint数
for(int i=0; i<descriptors.rows; ++i) {
cv::Mat d(descriptors, cv::Rect(0,i,descriptors.cols,1));
std::cout << i << ": " << d << std::endl;
}
And you have your result.

Related

Simulink S-Function Builder with External Library and Runtime Binary

I am trying to make a S-Function (written in C and using SDL library) in Simulink to read joystick values from the device and output them to Simulink. I used before the standard aerospace library joystick block, however, this does not support compiling (which is needed for Rapid Acceleration). Hence, I decided to write my own S-Function.
I managed to make a simple C program that uses SDL (I downloaded https://www.libsdl.org/download-2.0.php) to read values of joystick and print to terminal:
#include <stdio.h>
#include <unistd.h>
#include "SDL2/SDL.h"
static SDL_Joystick *joy = NULL;
int
main(int argc, char *argv[])
{
// ITIALIZE:
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
// Check for joystick
if (SDL_NumJoysticks() > 0) {
// Open joystick
joy = SDL_JoystickOpen(0);
if (joy) {
printf("Opened Joystick 0\n");
printf("Name: %s\n", SDL_JoystickNameForIndex(0));
printf("Number of Axes: %d\n", SDL_JoystickNumAxes(joy));
printf("Number of Buttons: %d\n", SDL_JoystickNumButtons(joy));
printf("Number of Balls: %d\n", SDL_JoystickNumBalls(joy));
} else {
printf("Could not open Joystick 0\n");
return 0;
}
}
SDL_JoystickEventState(SDL_IGNORE);
// READ VALUES:
for (int i = 1; i < 100; ++i){
SDL_JoystickUpdate();
for (int j = 0; j < SDL_JoystickNumAxes(joy); ++j) {
int value = (((int) SDL_JoystickGetAxis(joy, j)) + 32768);
printf("Axes %d: %d ", j, value);
}
printf("\n");
usleep(100000);
}
// CLOSE:
if (SDL_JoystickGetAttached(joy)) {
SDL_JoystickClose(joy);
}
return 1;
}
I compile the C code in Code::Blocks with linkers:
-lmingw32 -lSDL2main -lSDL2
The compiled .exe requires runtime binary SDL.dll, which is simply located in the same folder as the compilation, and everything works.
The problem is, how to transfer the above to work in Simulink environment? I have transferred the code into Simulink S-Function builder:
/* Includes_BEGIN */
#include "SDL2/SDL.h"
#include <stdio.h>
/* Includes_END */
/* Externs_BEGIN */
static SDL_Joystick *joy = NULL;
/* Externs_END */
void sunf_joystick_Start_wrapper(void)
{
/* Start_BEGIN */
// ITIALIZE:
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
// Check for joystick
if (SDL_NumJoysticks() > 0) {
// Open joystick
joy = SDL_JoystickOpen(0);
if (joy) {
ssPrintf("Opened Joystick 0\n");
ssPrintf("Name: %s\n", SDL_JoystickNameForIndex(0));
ssPrintf("Number of Axes: %d\n", SDL_JoystickNumAxes(joy));
ssPrintf("Number of Buttons: %d\n", SDL_JoystickNumButtons(joy));
ssPrintf("Number of Balls: %d\n", SDL_JoystickNumBalls(joy));
} else {
ssWarning("Warning:Joystick","Could not open Joystick 0\n");
}
}
SDL_JoystickEventState(SDL_IGNORE);
/* Start_END */
}
void sunf_joystick_Outputs_wrapper(real_T *y0)
{
/* Output_BEGIN */
SDL_JoystickUpdate();
for (int j = 0; j < SDL_JoystickNumAxes(joy); ++j) {
y0[j] = (((int) SDL_JoystickGetAxis(joy, j)) + 32768);
}
/* Output_END */
}
void sunf_joystick_Terminate_wrapper(void)
{
/* Terminate_BEGIN */
if (SDL_JoystickGetAttached(joy)) {
SDL_JoystickClose(joy);
}
/* Terminate_END */
}
and added the LIB_PATH and INCL_PATH to point for the SDL library:
S-function builder Libraries tab
However, I get a lot of similar error messages when trying to build through the GUI:
C:\Users\user\AppData\Local\Temp\mex_121831936796334_22096\sunf_joystick_wrapper.obj:sunf_joystick_wrapper.c:(.text+0xe): undefined reference to `SDL_InitSubSystem'
To me it seems that the libraries are not linked correctly. An idea how to fix this? I have tried to build it also with mex through MATLAB command line, not successful, and feels also wrong way to do it.
Also, any advice where the the runtime library SDL.dll should be stored or referenced if the compilation is successful?
All files in: https://github.com/JohannesSoikkeli/Simulink_joystick
Many thanks!

Highlight a widget partially in GTK+

I have a list box in part of my interface, and I want to highlight the GtkListBoxRows individually by progress. You load several files, and my program works on it each file individually, and I want to highlight the list box row like a progress bar. It is very similar to a progress bar, just the contents inside are buttons and some text. Is there a specific Cairo/Pango function that allows the recoloring?
I have a solution here using Gtkmm (should be easily translatable to C). I have a series of 5 buttons aligned horizontally inside a container and a "Make progress" button. When you click on it, child buttons in the container are updated to show the progress:
#include <iostream>
#include <gtkmm.h>
class MainWindow : public Gtk::ApplicationWindow
{
public:
MainWindow();
private:
Gtk::Grid m_container;
Gtk::Button m_progressButton;
int m_progressTracker = 0;
};
MainWindow::MainWindow()
: m_progressButton("Make progress...")
{
// Add five buttons to the container (horizontally):
for(int index = 0; index < 5; ++index)
{
Gtk::Button* button = Gtk::make_managed<Gtk::Button>("B" + std::to_string(index));
m_container.attach(*button, index, 0, 1, 1);
}
// Add a button to control progress:
m_container.attach(m_progressButton, 0, 1, 5, 1);
// Add handler to the progress button.
m_progressButton.signal_clicked().connect(
// Each time the button is clicked, the "hilighting" of the buttons
// in the container progresses until completed:
[this]()
{
Gtk::Widget* child = m_container.get_child_at(m_progressTracker, 0);
if(child != nullptr)
{
std::cout << "Making progress ..." << std::endl;
// Change the button's background color:
Glib::RefPtr<Gtk::CssProvider> cssProvider = Gtk::CssProvider::create();
cssProvider->load_from_data("button {background-image: image(cyan);}");
child->get_style_context()->add_provider(cssProvider, GTK_STYLE_PROVIDER_PRIORITY_USER);
// Update for next child...
++m_progressTracker;
}
}
);
// Make m_container a child of the window:
add(m_container);
}
int main(int argc, char *argv[])
{
std::cout << "Gtkmm version : " << gtk_get_major_version() << "."
<< gtk_get_minor_version() << "."
<< gtk_get_micro_version() << std::endl;
auto app = Gtk::Application::create(argc, argv, "org.gtkmm.examples.base");
MainWindow window;
window.show_all();
return app->run(window);
}
In your case, you will have to adapt the container and the signal (maybe you will need something else to trigger the redraw), but it should work pretty much the same as far as changing the background color is concerned. You can build this (using Gtkmm 3.24) with:
g++ main.cpp -o example.out `pkg-config --cflags --libs gtkmm-3.0`

arduino not writing to sd card

I have an Arduino with a Seeedstudio sd card shield v4.0 with a prototpye shield above that, and on that is a TMP36 temperature sensor and a red and two green LEDs, the red to show that it is "Ready" to log data, the first green to show that it is currently "logging data" and the last LED to show that the data was "Saved" to the SD card, which it dosent, at the beggining of the file, however, it creates the line "Testing 1, 2, 3..." in a txt file called TEST. in that same file there should be the data, but there is no data, it will write to the card in setup, but not in loop. Can anyone help me?
Code:
#include <toneAC.h>
#include <SPI.h>
#include <SD.h>
int readyLED = 2;
int startLED = 8;
int buzzer = 7;
int tempSensor = A0;
int readyButton = 5;
int sampleNo = 0;
int button_mode = 1;
int saveLED = 4;
File myFile;
void setup() {
// put your setup code here, to run once:
pinMode(readyLED, OUTPUT);
digitalWrite(readyLED, HIGH);
pinMode(saveLED, OUTPUT);
digitalWrite(saveLED, LOW);
pinMode(startLED, OUTPUT);
pinMode(buzzer, OUTPUT);
pinMode(10, OUTPUT);
pinMode(tempSensor, INPUT);
pinMode(readyButton, INPUT);
digitalWrite(readyLED, HIGH);
digitalWrite(startLED, LOW);
Serial.begin(9600);
while (!Serial){}
Serial.println("Initializing SD card...");
if(!SD.begin(4)){
Serial.println("Failed!");
return;
}
Serial.println("Success!");
myFile = SD.open("test.txt", FILE_WRITE);
if (myFile) {
Serial.println("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
delay(500);
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(readyLED, HIGH);
digitalWrite(startLED, LOW);
delay(700);
digitalWrite(startLED, HIGH);
delay(650);
int reading = analogRead(tempSensor);
float voltage = reading * 5.0;
voltage /= 1024.0;
float temperatureC = (voltage - 0.5) * 100;
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
Serial.print("Sample No. ");
sampleNo = sampleNo + 1;
Serial.print(sampleNo);
Serial.print(" Temperature: ");
Serial.print(temperatureF);
Serial.println(" F");
myFile = SD.open("test.txt", FILE_WRITE);
if(myFile){
Serial.println("Test.txt");
}
while(myFile.available()){
myFile.print("Sample No. ");
myFile.print(sampleNo);
myFile.print(" Temperature: ");
myFile.print(temperatureF);
myFile.println(" F");
}
delay(30);
digitalWrite(saveLED, HIGH);
delay(10);
digitalWrite(saveLED, LOW);
delay(10);
myFile.close();
}
You may want to check to make sure your while loop is actually being run. Since you know you can write to the SD card from void setup() you know your code inside the while loop works, but is the while loop actually being run, or is it evaluating to false and being skipped?
Have you considered the time it takes to write down data as an issue? You may be asking for it write down data before the Arduino code has time to process.

Transfer PixelBox data with boost

I get an image from an Ogre rendertaget.
I get the pixelbox of the image :
Ogre::RenderTarget *rt = _window;
rt->update();
int width = rt->getWidth();
int height = rt->getHeight();
std::cout << "width=" << width << std::endl;
std::cout << "height=" << height << std::endl;
uchar *data = new uchar[width * height * 3];
PixelBox pb(width, height, 1, PF_BYTE_RGB, data);
rt->copyContentsToMemory(pb);
After doing that, i want to get the pb.data (that's Ogre::uchar), write it in a buffer, and send it via a socket using boost. And don't see how to.
thanks.
Look at the http sync client for an example. The code you want is going to look like:
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << pb;
boost::asio::write(socket, request);

opencv get subimage in iphone

I am trying to get subimages with Opencv in iphone.What is the problem in this code?
error from console is: OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /Users/macmade/Desktop/OpenCV-iPhone/OpenCV/build/iPhoneSimulator/../.././tmp/OpenCV-2.0.0/src/cxcore/cxarray.cpp, line 2470
terminate called after throwing an instance of 'cv::Exception'
std::vector<IplImage*> vec_images;
int h = bw->height;
for (int i=0; i<Xleft.size(); ++i) {
CvRect rect = cvRect(Xleft[i], 0, avgx, h);
/* dst image */
IplImage* subimg;
/* copy ROI to subimg */
cvSetImageROI(bw, rect);
cvCopy(bw, subimg, NULL);
vec_images.push_back(subimg);
cvResetImageROI(bw);
}
for (int i=0; vec_images.size(); ++i) {
cvReleaseImage(&vec_images[i]);
}
You must initialize subimg before calling cvCopy.