Arduino String Parsing issue - c++

I have a problem, I am sending some data from a PC C++ app with this structure from a visual studio app:
puerto1.WriteLine(rpm + ";" + gea + ":" + speed + ";;" + fuel + "::" + boost + ";;;" + rtemp + ":::" + atemp + ";;;;" + gas + "::::" + brk + ";;;;;");
And then on the Arduino, I parse it in 9 different strings and when I want to display it on a screen it reports the problem of the pic attached.
It works correctly sometimes, but it stopped working correctly a few days ago and it haven't returned to work properly, it should print the strings indepently like:
XXX
XXX
XXX
XXX
XXX
Not like the image.
Arduino code:
#include <UTFTGLUE.h>
UTFTGLUE myGLCD(0, A2, A1, A3, A4, A0);
extern uint8_t BigFont[];
String command;
String part1;
String part2;
String part3;
String part4;
String part5;
String part6;
String part7;
String part8;
String part9;
void setup() {
Serial.begin(9600);
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
myGLCD.clrScr();
myGLCD.setColor(255, 255, 255);
myGLCD.setBackColor(0, 0, 0);
myGLCD.print("RPMs", 1, 10);
myGLCD.print("Gear", 1, 40);
myGLCD.print("Speed", 1, 70);
myGLCD.print("Fuel", 1, 100);
myGLCD.print("Boost", 1, 130);
myGLCD.print("Asphalt Temp", 1, 160);
myGLCD.print("Air Temp", 1, 190);
myGLCD.print("Gas", 1, 220);
myGLCD.print("Brake", 1, 250);
myGLCD.print("Engine Brake", 1, 280);
}
void loop() {
if (Serial.available()) {
char c = Serial.read();
if (c == '\n') {
parseCommand(command);
command = "";
} else {
command += c;
}
}
myGLCD.setColor(255, 255, 255);
myGLCD.setBackColor(0, 0, 0);
myGLCD.printNumI(val1, 5, 20);
myGLCD.print(part2, 5, 50);
myGLCD.printNumI(val3, 5, 80);
myGLCD.print(part4, 5, 110);
myGLCD.print(part5, 5, 140);
myGLCD.print(part6, 5, 170);
myGLCD.print(part7, 5, 200);
myGLCD.print(part8, 5, 230);
myGLCD.print(part9, 5, 260);
myGLCD.print(part10, 5, 290);
}
void parseCommand(String com) {
part1 = com.substring(0, com.indexOf(";"));
part2 = com.substring(com.indexOf(";") + 1, com.indexOf(":"));
part3 = com.substring(com.indexOf(":") + 1, com.indexOf(";;"));
part4 = com.substring(com.indexOf(";;") + 2, com.indexOf("::"));
part5 = com.substring(com.indexOf("::") + 2, com.indexOf(";;;"));
part6 = com.substring(com.indexOf(";;;") + 3, com.indexOf(":::"));
part7 = com.substring(com.indexOf(":::") + 3, com.indexOf(";;;;"));
part8 = com.substring(com.indexOf(";;;;") + 4, com.indexOf("::::"));
part9 = com.substring(com.indexOf("::::") + 4, com.indexOf(";;;;;"));
int val1 = part1.toInt();
int val3 = part3.toInt();
}
problem image

Related

Printer control language, PCL for 24bpp, 16 an gray

I used this link and added lots of enhancements related to GDI.
https://github.com/microsoft/Windows-driver-samples/tree/master/print/OEM%20Printer%20Customization%20Plug-in%20Samples/C%2B%2B/bitmap
The above samples generates a bitmap driver with output as a bitmap image. Now using the bitmap I am able to generate working PCL for monochrome. I need some help for enhancing it further to generate PCL for 16bpp, 24 color and gray scale
Can anyone suggest some samples where I could see the PCL commands written in C++?
The monochrome part works correctly but the remaining color or gray scale just produce a blank image. I am using GhostPCL to convert to jpeg for testing purposes.
Can anyone provide a sample for where given an appropriate bitmap there is some PCLstream as output?
If you can't provide an entire working sample, how about things in commands which need to be addressed.
The one obvious thing is the buffer, rowsize.
This is the PCL for monochrome.
https://mega.nz/file/rNlFFRYL#CDK_l6s9KojLzywI3drsO1yt_OaK7-n5TNWdj1x8Aa4
This is the PCL for TrueColor same document. Nothing is printed except text
https://mega.nz/file/jI0lXRxZ#DmjLiDlNR8CfisN9UsRgz0F-FwXgOC0DCkaRPxqYCh4
I am using ghostPCL to convert to jpeg.
Code for monochrome:
//Header
// Universal Exit
char bufUnivExit[10];
StringCchPrintfA(bufUnivExit, 10, "%c%s", 27, "%-12345X"); // 9 chars
MoveMemory(pOemPDEV->pBufStart, bufUnivExit, 10);
dwOffset += 9;
// PJL
char bufPJL[38];
StringCchPrintfA(bufPJL, 38, "%s%c%c", "#PJL COMMENT ROMFOBMAYCE TEST-PRINT", 13, 10); // 37 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufPJL, 38);
dwOffset += 37;
// PCL Esc
char bufEsc[3];
StringCchPrintfA(bufEsc, 3, "%c%s", 27, "E"); // 2 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufEsc, 3);
dwOffset += 2;
// Raster Res
char bufRes[8];
StringCchPrintfA(bufRes, 8, "%c%s%d%s", 27, "*t", pPubDM->dmYResolution, "R"); // 7 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufRes, 8);
dwOffset += 7;
// Units of Measure
char bufUOM[8];
StringCchPrintfA(bufUOM, 8, "%c%s%d%s", 27, "&u", pPubDM->dmYResolution, "D"); // 7 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufUOM, 8);
dwOffset += 7;
// Raster Presentation
char bufPres[6];
StringCchPrintfA(bufPres, 6, "%c%s", 27, "*r3F"); // 5 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufPres, 6);
dwOffset += 5;
// Orientation
char bufOrient[6];
if (pPubDM->dmOrientation == 1)
orient = 0;
else
orient = 1;
StringCchPrintfA(bufOrient, 6, "%c%s%d%s", 27, "&l", orient, "O"); // 5 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufOrient, 6);
dwOffset += 5;
// Paper Size
char bufPaperSize[6];
if (pPubDM->dmPaperSize == 1)
pageSize = 2;
else
pageSize = 3;
StringCchPrintfA(bufPaperSize, 6, "%c%s%d%s", 27, "&l", pageSize, "A"); // 5 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufPaperSize, 6);
dwOffset += 5;
// Set horizontal and vertical registration (page margins)
char bufRegistration[14];
StringCchPrintfA(bufRegistration, 14, "%c%s", 27, "&l-180u-360Z"); // 13 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufRegistration, 14);
dwOffset += 13;
//Code for Page
BYTE bitmapRow[1050];
BYTE compRow[2100];
DWORD dwRowSize = 0;
DWORD dwCompPCLBitmapSize = 0;
for (i = 0; i < pso->sizlBitmap.cy; i++) {
// Zero Memory hack for bottom of form black line
if (*(((PBYTE &)pso->pvScan0) + (i * pso->lDelta) + 319) == 0xFF)
ZeroMemory(((PBYTE &)pso->pvScan0) + (i * pso->lDelta), 320);
// Copy the bitmap scan line into bitmapRow and send them off to be compressed
ZeroMemory(bitmapRow, 1050);
ZeroMemory(compRow, 2100);
MoveMemory(bitmapRow, ((PBYTE &)pso->pvScan0) + (i * pso->lDelta), pso->lDelta);
dwRowSize = CompressBitmapRow(compRow, bitmapRow, pso->lDelta);
// Create PCL Row Heading
char bufPCLLineHead[9];
StringCchPrintfA(bufPCLLineHead, 9, "%c%s%d%s", 27, "*b", dwRowSize, "W");
if ((dwCompPCLBitmapSize + dwRowSize + strlen(bufPCLLineHead))
> pOemPDEV->dwCompBitmapBufSize) {
if (!GrowCompBitmapBuf(pOemPDEV)) {
//ZeroMemory(traceBuff, 256);
//StringCchPrintf(traceBuff, 256,
// L"Compressed bitmap buffer could not allocate more memory.");
//WriteTraceLine(traceBuff);
}
}
if (pOemPDEV->pCompBitmapBufStart) {
// write the PCL line heading to the buffer
MoveMemory(pOemPDEV->pCompBitmapBufStart + dwCompPCLBitmapSize,
bufPCLLineHead, strlen(bufPCLLineHead));
dwCompPCLBitmapSize += strlen(bufPCLLineHead);
// write the compressed row to the buffer
MoveMemory(pOemPDEV->pCompBitmapBufStart + dwCompPCLBitmapSize,
compRow, dwRowSize);
dwCompPCLBitmapSize += dwRowSize;
}
}
// Calculate size and create buffer
dwPageBufferSize = 21;
if (!firstPage)
dwPageBufferSize++;
bGrowBuffer(pOemPDEV, dwPageBufferSize);
// Add all Raster Header Lines
if (!firstPage)
{
// Add a Form Feed
char bufFormFeed[2];
StringCchPrintfA(bufFormFeed, 2, "%c", 12); // 1 char
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufFormFeed, 2);
dwOffset += 1;
}
// Position cursor at X0, Y0
char bufXY[8];
StringCchPrintfA(bufXY, 8, "%c%s", 27, "*p0x0Y"); // 7 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufXY, 8);
dwOffset += 7;
// Start Raster Graphics
char bufStartRas[6];
StringCchPrintfA(bufStartRas, 6, "%c%s", 27, "*r1A"); // 5 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufStartRas, 6);
dwOffset += 5;
// Raster Encoding - Run-Length Encoding
char bufRasEncoding[6];
StringCchPrintfA(bufRasEncoding, 6, "%c%s", 27, "*b1M"); // 5 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufRasEncoding, 6);
dwOffset += 5;
// Write out bitmap header PCL
dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, pOemPDEV->pBufStart, dwPageBufferSize);
// Write out PCL plus compressed bitmap bytes
dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, pOemPDEV->pCompBitmapBufStart, dwCompPCLBitmapSize);
// End Raster Graphics
char bufEndRas[5];
StringCchPrintfA(bufEndRas, 5, "%c%s", 27, "*rB"); // 4 chars
MoveMemory(pOemPDEV->pBufStart + dwOffset, bufEndRas, 5);
// Write out PCL end bitmap
dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, bufEndRas, 4);
Can anyone suggest? I don't have working knowledge of PCL or C++ except learning it like this.

Writing to File in Python, Reading From File with Arduino

I'm currently using Python 2.7 to pull pixel information from a series of bitmaps, and writing 24 bits of information to a file (with an arbitrary extension, ".bfs", to make it easy to find down the pipeline), 8 bits for position x, 8 bits for position y, 16 bits for color.
from PIL import Image
import struct
filename = raw_input('Please choose destination filename: ')
file_in = [0]*27
im = [0]*27
for i in range(1,27):
file_in[i] = str(i)+".bmp"
im[i] = Image.open(file_in[i])
file_out = open(filename+".bfs", 'w')
readable_out = open(filename+".txt", 'w')
for q in range(1,27):
pix = im[q].load()
width, height = im[q].size
for y in range (height):
for x in range (width):
rgb = pix[x,y]
red = rgb[0]
green = rgb[1]
blue = rgb[2]
Uint16_val = (((31*(red+4))/255)<<11) | (((63*(green+2))/255)<<5) | ((31*(blue+4))/255)
hex_16 = int('%.4x'%Uint16_val, 16)
print(str(x)+", "+str(y)+", "+str(hex_16)+"\n")
readable_out.write(str(x)+", "+str(y)+", "+str(hex_16)+"\n")
file_out.write(struct.pack('<1B', x))
file_out.write(struct.pack('<1B', y))
file_out.write(struct.pack('<1H', hex_16))
On the PC side everything is coming out clean how I expect (this is copied from a .txt file that I output and format to make it easier to read):
0, 0, 40208
1, 0, 33544
2, 0, 33544
3, 0, 39952
4, 0, 39944
5, 0, 33544
6, 0, 39688
7, 0, 39952
8, 0, 39944
9, 0, 33544
10, 0, 33800
11, 0, 39952
12, 0, 39952
13, 0, 33544
14, 0, 33800
15, 0, 48400
From here I'm taking the .bfs file and loading it onto an SD card for an Arduino Uno to read from. The Arduino code is supposed to read from the SD card, and output the x, y, and color values to a TFT LCD. Here is the Arduino Code:
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
#include <SD.h>
#define TFT_CS 10 // Chip select line for TFT display
#define TFT_RST 9 // Reset line for TFT (or see below...)
#define TFT_DC 8 // Data/command line for TFT
#define SD_CS 4 // Chip select line for SD card
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
void setup(void) {
Serial.begin(9600);
tft.initR(INITR_144GREENTAB);
Serial.print("Initializing SD card...");
if (!SD.begin(SD_CS)) {
Serial.println("failed!");
return;
}
Serial.println("OK!");
tft.fillScreen(0x0000);
}
uint32_t pos = 0;
uint8_t x,y;
uint8_t buffpix[3];
uint16_t c;
void loop() {
bfsDraw("image.bfs");
}
#define BUFFPIXEL 20
void bfsDraw(char *filename) {
File bfsFile;
int w, h, row, col;
uint8_t x,y;
uint16_t c;
uint32_t pos = 0, startTime = millis();
if((0 >= tft.width()) || (0 >= tft.height())) return;
if ((bfsFile = SD.open(filename)) == NULL) {
Serial.print("File not found");
return;
}
w = 128;
h = 128;
tft.setAddrWindow(0, 0, 0+w-1, 0+h-1);
for (row=0; row<h; row++) {
for (col=0; col<w; col++) {
x = bfsFile.read();
Serial.print(x);
Serial.print(", ");
y = bfsFile.read();
Serial.print(y);
Serial.print(", ");
c = read16(bfsFile);
Serial.print(c);
Serial.print(" ");
Serial.println(" ");
tft.drawPixel(x,y,c);
}
}
}
uint8_t read8(File f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read();
return result;
}
uint16_t read16(File f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read();
((uint8_t *)&result)[1] = f.read();
return result;
}
I have some print statements around the code that reads from the card before sending out to the TFT, and instead of matching the file that (I think) I wrote it outputs like this:
0, 0, 40208
1, 0, 33544
2, 0, 33544
3, 0, 39952
4, 0, 39944
5, 0, 33544
6, 0, 39688
7, 0, 39952
8, 0, 39944
9, 0, 33544
13, 10, 2048
132, 11, 4096
156, 12, 4096
As you can see the reading from the Arduino starts out matching the writing of the Python script, but after 9 the "X" byte has shifted into the middle instead of the leading position. My question, is what is causing this shift, after x = 9? is this a little endian versus big endian issue?
Thanks for your help!
You opened your file in text mode, not binary mode. On Windows, that means that every newline character (byte value 10) that you write gets converted into carriage return + linefeed (byte values 13, 10). Use 'wb' for the mode when opening the .bfs file.
Note that writing the coordinates of each pixel into the file is insane - you're doubling the size of the file for absolutely no benefit. You can easily recreate the coordinates as you're reading the file - in fact you're ALREADY DOING SO, in the form of the row and col variables!

Ncurses place cursor in correct panel

I am making an application which has several windows, each contained inside of a panel. One of these windows in particular must take input from the keyboard. I also need to be able to detect special keys like the F keys and the arrow keys. My current application is doing this currently. However the cursor is not in the proper location even after I call wmove(my_wins[1], 3, 2).
How do I move the cursor to be in the proper panel at the proper location? I would like the terminal cursor to be in my second window (my_wins[1]), at the next empty space that I want to take characters from. In this case, this is the 3rd row of my_wins[1] after the last character entered into this line.
My code:
#include <panel.h>
#include <ncurses.h>
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <vector>
WINDOW *my_wins[4];
PANEL* my_panels[4];
// forward declarations
void make_screen();
void clear_win1();
void get_input();
int main()
{
initscr();
cbreak();
noecho();
make_screen();
get_input();
endwin();
}
void get_input()
{
// enable f-keys and arrow keys
keypad(my_wins[1], TRUE);
int ch;
std::string str = "";
std::vector<std::string> cmds;
while ((ch = wgetch(my_wins[1])) != KEY_F(1))
{
switch(ch)
{
case 127: // delete
if (str.size() > 0)
{
str.erase(str.size()-1);
}
break;
case '\n':
cmds.push_back(str);
str = "";
break;
default:
if (ch >= ' ' || ch <= 126)
{
str += (char) ch;
}
break;
}
clear_win1();
mvwprintw(my_wins[1], 3, 2, "%s", str.c_str());
wmove(my_wins[1], 3, 2+str.size());
update_panels();
doupdate();
}
}
void make_screen()
{
int maxx, maxy;
getmaxyx(stdscr, maxy, maxx);
float win1y = maxy;
float win1x = (2.0/7)*maxx;
float win2y = (3.0/5)*maxy;
float win2x = (3.0/7)*maxx;
float win3y = (3.0/5)*maxy;
float win3x = (2.0/7)*maxx;
float win4y = (2.0/5)*maxy + 1;
float win4x = (5.0/7)*maxx;
my_wins[0] = newwin(win1y, win1x, 0, 0);
my_wins[1] = newwin(win2y, win2x, 0, win1x);
my_wins[2] = newwin(win3y, win3x, 0, win1x+win2x);
my_wins[3] = newwin(win4y, win4x, win2y, win1x);
/*
* Create borders around the windows so that you can see the effect
* of panels
*/
for(int i = 0; i < 4; ++i)
{
box(my_wins[i], 0, 0);
}
my_panels[0] = new_panel(my_wins[0]);
my_panels[1] = new_panel(my_wins[1]);
my_panels[2] = new_panel(my_wins[2]);
my_panels[3] = new_panel(my_wins[3]);
mvwprintw(my_wins[0], 2, 2, "Yelp data");
mvwprintw(my_wins[1], 2, 2, "I/O Window");
mvwprintw(my_wins[2], 2, 2, "Menu items");
mvwprintw(my_wins[3], 2, 2, "Tables");
mvwprintw(my_wins[3], 3, 2, "maxy: %d, maxx: %d", maxy, maxx);
mvwprintw(my_wins[3], 4, 2, "win1y: %f, win1x: %f", win1y, win1x);
mvwprintw(my_wins[3], 5, 2, "win2y: %f, win2x: %f", win2y, win2x);
mvwprintw(my_wins[3], 6, 2, "win3y: %f, win3x: %f", win3y, win3x);
mvwprintw(my_wins[3], 7, 2, "win4y: %f, win4x: %f", win4y, win4x);
mvwprintw(my_wins[1], 3, 2, "");
update_panels();
doupdate();
}
void clear_win1()
{
werase(my_wins[1]);
box(my_wins[1], 0, 0);
mvwprintw(my_wins[1], 2, 2, "I/O Window");
update_panels();
doupdate();
}
Your example puts the wmove before the updates to the screen. Those updates leave the cursor in whatever location made sense for minimal cursor movement when updating the screen.
This change shows how to do what you're asking:
$ diff -u foo.c.orig foo.c
--- foo.c.orig 2017-03-06 18:56:26.000000000 -0500
+++ foo.c 2017-03-06 19:00:03.568868347 -0500
## -33,6 +33,7 ##
std::string str = "";
std::vector<std::string> cmds;
+ wmove(my_wins[1], 3, 2+str.size());
while ((ch = wgetch(my_wins[1])) != KEY_F(1))
{
switch(ch)
## -56,9 +57,9 ##
}
clear_win1();
mvwprintw(my_wins[1], 3, 2, "%s", str.c_str());
- wmove(my_wins[1], 3, 2+str.size());
update_panels();
doupdate();
+ wmove(my_wins[1], 3, 2+str.size());
}
}

Anisotropic Diffusion

I have converted this Matlab Anisotropic Diffusion code to C++ but I am not getting the desired output. All I am getting is a black image. Can someone please check my code and give any suggestions? Below is my code:
const double lambda = 1 / 7;
const double k = 30;
const int iter = 1;
int ahN[3][3] = { {0, 1, 0}, {0, -1, 0}, {0, 0, 0} };
int ahS[3][3] = { {0, 0, 0}, {0, -1, 0}, {0, 1, 0} };
int ahE[3][3] = { {0, 0, 0}, {0, -1, 1}, {0, 0, 0} };
int ahW[3][3] = { {0, 0, 0}, {1, -1, 0}, {0, 0, 0} };
int ahNE[3][3] = { {0, 0, 1}, {0, -1, 0}, {0, 0, 0} };
int ahSE[3][3] = { {0, 0, 0}, {0, -1, 0}, {0, 0, 1} };
int ahSW[3][3] = { {0, 0, 0}, {0, -1, 0}, {1, 0, 0} };
int ahNW[3][3] = { {1, 0, 0}, {0, -1, 0}, {0, 0, 0} };
Mat hN = Mat(3, 3, CV_32FC1, &ahN);
Mat hS = Mat(3, 3, CV_32FC1, &ahS);
Mat hE = Mat(3, 3, CV_32FC1, &ahE);
Mat hW = Mat(3, 3, CV_32FC1, &ahW);
Mat hNE = Mat(3, 3, CV_32FC1, &ahNE);
Mat hSE = Mat(3, 3, CV_32FC1, &ahSE);
Mat hSW = Mat(3, 3, CV_32FC1, &ahSW);
Mat hNW = Mat(3, 3, CV_32FC1, &ahNW);
void anisotropicDiffusion(Mat &output, int width, int height) {
//mat initialisation
Mat nablaN, nablaS, nablaW, nablaE, nablaNE, nablaSE, nablaSW, nablaNW;
Mat cN, cS, cW, cE, cNE, cSE, cSW, cNW;
//depth of filters
int ddepth = -1;
//center pixel distance
double dx = 1, dy = 1, dd = sqrt(2);
double idxSqr = 1.0 / (dx * dx), idySqr = 1.0 / (dy * dy), iddSqr = 1 / (dd * dd);
for (int i = 0; i < iter; i++) {
//filters
filter2D(output, nablaN, ddepth, hN);
filter2D(output, nablaS, ddepth, hS);
filter2D(output, nablaW, ddepth, hW);
filter2D(output, nablaE, ddepth, hE);
filter2D(output, nablaNE, ddepth, hNE);
filter2D(output, nablaSE, ddepth, hSE);
filter2D(output, nablaSW, ddepth, hSW);
filter2D(output, nablaNW, ddepth, hNW);
//exponential flux
cN = nablaN / k;
cN.mul(cN);
cN = 1.0 / (1.0 + cN);
//exp(-cN, cN);
cS = nablaS / k;
cS.mul(cS);
cS = 1.0 / (1.0 + cS);
//exp(-cS, cS);
cW = nablaW / k;
cW.mul(cW);
cW = 1.0 / (1.0 + cW);
//exp(-cW, cW);
cE = nablaE / k;
cE.mul(cE);
cE = 1.0 / (1.0 + cE);
//exp(-cE, cE);
cNE = nablaNE / k;
cNE.mul(cNE);
cNE = 1.0 / (1.0 + cNE);
//exp(-cNE, cNE);
cSE = nablaSE / k;
cSE.mul(cSE);
cSE = 1.0 / (1.0 + cSE);
//exp(-cSE, cSE);
cSW = nablaSW / k;
cSW.mul(cSW);
cSW = 1.0 / (1.0 + cSW);
//exp(-cSW, cSW);
cNW = nablaNW / k;
cNW.mul(cNW);
cNW = 1.0 / (1.0 + cNW);
//exp(-cNW, cNW);
output = output + lambda * (idySqr * cN.mul(nablaN) + idySqr * cS.mul(nablaS) +
idxSqr * cW.mul(nablaW) + idxSqr * cE.mul(nablaE) +
iddSqr * cNE.mul(nablaNE) + iddSqr * cSE.mul(nablaSE) +
iddSqr * cNW.mul(nablaNW) + iddSqr * cSW.mul(nablaSW));
}
}
Resolved in c#. Easy of translate to c++
You need this variables:
IMAGE[height, width] = integer array with stored Image
height = height of images in pixels
width = width of images in pixels
/// <summary>Perona & Malik anisotropic difusion filter. (squared formula)</summary>
/// <param name="data">Image data</param>
/// <param name="dt">Heat difusion value. Upper = more rapid convergence.</param>
/// <param name="lambda">The shape of the diffusion coefficient g(), controlling the Perona Malik diffusion g(delta) = 1/((1 + delta2) / lambda2). Upper = more blurred image & more noise removed</param>
/// <param name="interations">Determines the maximum number of iteration steps of the filter. Upper = less speed & more noise removed</param>
private void PeronaMalik(int[,] image, double dt, int lambda, int interations)
{
try
{
//test parameters
if (dt < 0)
throw new Exception("DT negative value not allowed");
if (lambda < 0)
throw new Exception("lambda must be upper of 0");
if (interations <= 0)
throw new Exception("Iterations must be upper of 0");
//Make temp image
int[,] temp = new int[height, width];
Array.Copy(image, temp, image.Length);
//Precalculate tables (for speed up)
double[] precal = new double[512];
double lambda2 = lambda * lambda;
for (int f = 0; f < 512; f++)
{
int diff = f - 255;
precal[f] = -dt * diff * lambda2 / (lambda2 + diff * diff);
}
//Apply the filter
for (int n = 0; n < interations; n++)
{
for (int h = 0; h < height; h++)
for (int w = 0; w < width; w++)
{
int current = temp[h, w];
int px = w - 1;
int nx = w + 1;
int py = h - 1;
int ny = h + 1;
if (px < 0)
px = 0;
if (nx >= width)
nx = width - 1;
if (py < 0)
py = 0;
if (ny >= height)
ny = height - 1;
image[h, w] = (int)(precal[255 + current - temp[h, px]] +
precal[255 + current - temp[h, nx]] +
precal[255 + current - temp[py, w]] +
precal[255 + current - temp[ny, w]]) +
temp[h, w];
}
}
}
catch (Exception ex) { throw new Exception(ex.Message + "\r\nIn PeronaMalik"); }
}
The solution is for equation 2. If you want equation 1 (exponential), you can change the ecuation in precal table for this:
precal[f] = -dt * delta * Math.Exp(-(delta * delta / lambda2));
Looks like you need to assign multiplication result:
Mat C = A.mul(B);
And
int ahN[3][3] ....
should be
float ahN[3][3] ....

How to change fontsize on drawText?

QString str = QString::number((double)i, 'd', 1);
painter->drawText(100 + i * 800/9 - 6, 910, 40, 40, 0, str );
I would like to increase fontSize to 2x what is showing?
You could try something like this (haven't compiled code to see if it works!):
QFont font = painter->font() ;
/* twice the size than the current font size */
font.setPointSize(font.pointSize() * 2);
/* set the modified font to the painter */
painter->setFont(font);
/* draw text etc. */
painter.drawText(....);
Figured it out:
QFont font;
font.setPixelSize(12);
for(int i = 0; i < 10; i++){
painter->drawLine(100, 100 + i * 800/9, 900, 100 + i * 800/9);
str = QString::number((double)9 - i, 'd', 1);
painter->setFont(font);
painter->drawText(75, 100 + i * 800/9 - 6, 40, 40, 1, str);
}
this is the easiest way
painter.setFont(QFont("times",22)); //22 is a number which you have to change