New test obj files generated

This commit is contained in:
nicolas 2025-02-28 00:02:08 +01:00
parent 7bd2bf4602
commit c743403969
2 changed files with 0 additions and 1196 deletions

View File

@ -1,681 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
#include <unistd.h>
#include <time.h>
#include <linux/videodev2.h>
#include "imageRec.h"
#include "cmdTcpipClient.h"
imageBuffer* buffers[3];
struct pixel_list maxima[32];
unsigned char* buffer;
int useTcpIp = 0;
int silent = 0;
int tcpsilent = 0;
static int xioctl(int fd, int request, void* arg)
{
int r;
do r = ioctl(fd, (unsigned long)request, arg);
while (-1 == r && EINTR == errno);
return r;
}
int configImageFormat(int fd, struct v4l2_cropcap *cropcap, unsigned int camWidth, unsigned int camHight)
{
struct v4l2_capability caps = {};
if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &caps))
{
perror("Querying capabilities failed");
return 1;
}
if (!silent) printf("Driver caps:\n"
" Driver: \"%s\"\n"
" Card: \"%s\"\n"
" Bus: \"%s\"\n"
" Version: %d.%d\n"
" Capabilities: %08x\n",
caps.driver, caps.card, caps.bus_info, (caps.version >> 16) && 0xff,
(caps.version >> 24) && 0xff, caps.capabilities);
cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == xioctl(fd, VIDIOC_CROPCAP, cropcap))
{
perror("Querying cropping capabilities failed");
return 1;
}
int formatIsSupported = 0;
struct v4l2_fmtdesc fmtdesc = { 0 };
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
char fourcc[5] = { 0 };
char c, e;
while (0 == xioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc))
{
strncpy(fourcc, (char*)& fmtdesc.pixelformat, 4);
if (fmtdesc.pixelformat == V4L2_PIX_FMT_YUYV)
formatIsSupported = 1;
c = fmtdesc.flags & 1 ? 'C' : ' ';
e = fmtdesc.flags & 2 ? 'E' : ' ';
if (!silent) printf(" %s: %c%c %s\n", fourcc, c, e, fmtdesc.description);
fmtdesc.index++;
}
if (!formatIsSupported)
{
perror("Pixel format is not supported\n");
return 1;
}
struct v4l2_format fmt = { 0 };
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = camWidth;
fmt.fmt.pix.height = camHight;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_NONE;
if (!silent) printf("Requested camera settings:\n"
" Width: %d\n"
" Height: %d\n"
" Pixel format: %s\n",
fmt.fmt.pix.width,
fmt.fmt.pix.height,
fourcc);
if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
{
perror("Setting pixel format failed");
return 1;
}
strncpy(fourcc, (char*)& fmt.fmt.pix.pixelformat, 4);
if (!silent) printf("Selected camera settings:\n"
" Width: %d\n"
" Height: %d\n"
" Pixel format: %s\n",
fmt.fmt.pix.width,
fmt.fmt.pix.height,
fourcc);
return 0;
}
int initMmap(int fd)
{
struct v4l2_requestbuffers req = { 0 };
req.count = 1;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req))
{
perror("Requesting buffer failed (initMmap)");
return 1;
}
struct v4l2_buffer buf = { 0 };
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
{
perror("Querying buffer failed (initMmap)");
return 1;
}
buffer = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
return 0;
}
int captureImage(int fd, imageBuffer* destBuffer, unsigned int targetBufferSize)
{
unsigned int buffSize;
struct v4l2_buffer buf = { 0 };
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
{
perror("Query buffer failed (captureImage)");
return 1;
}
if (-1 == xioctl(fd, VIDIOC_STREAMON, &buf.type))
{
perror("Query start Capture failed");
return 1;
}
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
struct timeval tv = { 0 };
tv.tv_sec = 2;
int r = select(fd + 1, &fds, NULL, NULL, &tv);
if (-1 == r)
{
perror("Waiting for frame timed out");
return 1;
}
if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf))
{
perror("Retrieving frame failed");
return 1;
}
if (buf.bytesused / 2 > targetBufferSize)
buffSize = targetBufferSize;
else
buffSize = buf.bytesused / 2;
//Extract 8 Bit monocrome Y data from YUYV
for (int i = 0; i < buffSize; i++)
destBuffer[i] = (imageBuffer)buffer[i * 2] * 0x100;
return 0;
}
void printOut(char text[])
{
int i = 0;
if (useTcpIp && !tcpsilent)
{
while (text[i] != 0) i++;
sendTcpData((char*)text, i);
}
else
{
if (!silent) printf("%s", text);
}
}
void printOutChar(char character)
{
if (useTcpIp)
sendTcpData(&character, 1);
else
printf("%c", character);
}
void numberToString(int number, int divPos) {
int i = 10000;
int dCount;
int tempVal;
char divVal;
if (number < 0)
{
printOutChar('-');
number *= -1;
}
if (number)
{
dCount = 5 - divPos;
tempVal = number;
while (i)
{
if (number >= i)
{
divVal = (char)(tempVal / i);
printOutChar(divVal + 48);
tempVal -= divVal * i;
}
else if (dCount < 2)
{
printOutChar('0');
}
i /= 10;
dCount -= 1;
if (!dCount && i) printOutChar('.');
}
}
else
{
printOutChar('0');
}
}
int write16BitTiff(unsigned short* imageData, unsigned int width, unsigned int height, char* filePath)
{
FILE* f;
const unsigned char ofst = 0x86; //134=4+4+2+10*12+4
unsigned char iwlo = (unsigned char)(width & 0xFF);
unsigned char iwhi = (unsigned char)(width >> 8);
unsigned char ihlo = (unsigned char)(height & 0xFF);
unsigned char ihhi = (unsigned char)(height >> 8);
unsigned int imagePixels = width * height;
unsigned int imageBytes = imagePixels * 2;
unsigned char iblo = (unsigned char)(imageBytes & 0xFF);
unsigned char ibhi = (unsigned char)((imageBytes >> 8) & 0xFF);
unsigned char ibvh = (unsigned char)(imageBytes >> 16);
unsigned char file_header[] =
{
'I', 'I', 42, 0, // Little endian magic number
0x08, 0x00, 0x00, 0x00, // IFD header at byte 8
0x0A, 0x00, // 10 IFD tags
0xfe, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //TIFFTAG_SUBFILETYPE = 0
0x00, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, iwlo, iwhi, 0x00, 0x00, //TIFFTAG_IMAGEWIDTH = *
0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, ihlo, ihhi, 0x00, 0x00, //TIFFTAG_IMAGELENGTH = *
0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, //BITS_PER_SAMPLE = 16
0x03, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, //TIFFTAG_COMPRESSION = 1 (Non)
0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, //TIFFTAG_PHOTOMETRIC = 1 (BlackIsZero)
0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, ofst, 0x00, 0x00, 0x00, //TIFFTAG_STRIPOFFSETS (image data address)
0x12, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, //TIFFTAG_ORIENTATION = 1 (start top left)
0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, //TIFFTAG_SAMPLESPERPIXEL = 1
0x17, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, iblo, ibhi, ibvh, 0x00, //TIFFTAG_STRIPBYTECOUNTS = 1
0x00, 0x00, 0x00, 0x00
};
f = fopen(filePath, "wb");
if (f > 0)
{
fwrite(file_header, 1, sizeof(file_header), f);
fwrite(imageData, 2, imagePixels, f);
fclose(f);
}
return (f > 0);
}
int main(int argc, char* argv[])
{
int exitFlag = 0;
char buff[1];
int cbuff = 0;
int nbuff = 0;
int itemCount = 0;
int port = 0;
char* deviceName = "/dev/video0";
char* filePath = "out.tif";
imageBuffer* tmpib;
const int buffCount = 3;
char* pEnd = 0;
unsigned int buffSize;
unsigned int camWidth = 640;
unsigned int camHeight = 480;
int maxNumb = 32;
int maxMaxNumb = sizeof(maxima) / sizeof(struct pixel_list);
char* commandStr = "";
int i = 0;
int j;
int fnIncrPos = -1;
int fnIncr = 0;
while(i < argc)
{
if (*argv[i] == '-')
{
switch (*(argv[i] + 1))
{
case 'p':
pEnd = 0;
i++;
if (*commandStr)
printf("Option -p is skiped because -c is specified\n");
else
if (i < argc) port = strtol(argv[i], &pEnd, 10);
break;
case 'c':
i++;
if (port)
printf("Option -c is skiped because -p is specified\n");
else
if (i < argc) commandStr = argv[i];
break;
case 'd':
i++;
if (i < argc)
deviceName = argv[i];
break;
case 'f':
i++;
if (i < argc)
{
j = 0;
filePath = argv[i];
while (filePath[j] != 0)
{
if (filePath[j] == '#') fnIncrPos = j;
j++;
}
}
break;
case 'r':
i++;
if (i < argc)
{
pEnd = 0;
camWidth = (unsigned int)strtol(argv[i], &pEnd, 10);
if (*pEnd != 0 && *(pEnd + 1) != 0)
camHeight = strtol(pEnd + 1, &pEnd, 10);
}
break;
case 'n':
i++;
if (i < argc)
maxNumb = strtol(argv[i], &pEnd, 10);
if (maxNumb > maxMaxNumb) maxNumb = maxMaxNumb;
break;
case 's':
silent = 1;
break;
case '?':
case 'h':
case '-':
printf("Usage: imagerec [-options]\n");
printf("options:\n");
printf(" -h show help\n");
printf(" -c commands ASCII command string\n");
printf(" -p port TCP/IP-port to listen on\n");
printf(" -d device capture device name\n");
printf(" -r whidth*hight image resolution\n");
printf(" -n pixels max number of pixels for l command\n");
printf(" -f file file path for w command (# for index)\n");
printf(" -d return result data only\n");
printf("\n");
printf("examples: imagerec -d /dev/video0 -r 640*480 -p 5044\n");
printf(" imagerec -d /dev/video0 -r 640*480 -c cgnexCngml -s\n");
printf(" imagerec -d /dev/video0 -r 640*480 -c cgnexCnw -f result.tif\n");
printf(" imagerec -d /dev/video0 -r 640*480 -c cgnwexsonwrCnw -f result#.tif\n");
printf("\n");
printf("single byte ASCII commands:\n");
printf(" c capture image\n");
printf(" n normalize image\n");
printf(" g apply gausian blur\n");
printf(" e edge detection with sobel filter, must be\n");
printf(" folowd by 'x', 'o' or a hough transformation\n");
printf(" x remove non edge pixel, must be folowd by\n");
printf(" 'o' or a hough transformation\n");
printf(" o convert directional slope to absolute slope\n");
printf(" C circle hough transformation\n");
printf(" L line hough transformation\n");
printf(" H line hough transformation (horizontal only)\n");
printf(" V line hough transformation (vertical only)\n");
printf(" M miniscus hough transformation\n");
printf(" b binarize\n");
printf(" m remove non-local-maxima pixels\n");
printf(" l list brightes pixels (from max. 32 non black pixels)\n");
printf(" p list brightes pixel clusters (3x3)\n");
printf(" q close connection\n");
printf(" s store a copy of the current buffer\n");
printf(" r recall a copy of the stored buffer\n");
printf(" w write buffer to disk (TIF format)\n");
printf(" z set index for output file name to zero\n");
printf(" d show result data only\n");
printf(" i show info and result data (default)\n");
printf("\n");
printf("example: echo \"cngexCngmlq\" | nc localhost 5044\n");
return 0;
default:
printf("Unknown option: -%c\n", *(argv[i] + 1));
printf("Type imagerec -h for help\n");
return 0;
}
}
i++;
}
if (!silent)
{
if (port > 0)
printf("Start up ImageRecTool, listen on tcp port %i\n", port);
else
printf("Start up ImageRecTool\n", port);
printf("Type imagerec -h for help\n");
}
int fd = open((const char*)deviceName, O_RDWR);
if (fd == -1)
{
perror("Opening video device failed");
return 1;
}
struct v4l2_cropcap crcap = { 0 };
if (configImageFormat(fd, &crcap, camWidth, camHeight))
return 1;
buffSize = (unsigned)setImageSize((int)crcap.bounds.width, (int)crcap.bounds.height);
for (int i = 0; i < buffCount; i++)
{
buffers[i] = (imageBuffer*)malloc(buffSize * sizeof(imageBuffer));
}
if (initMmap(fd))
return 1;
if (port > 0)
{
if (!setupCmdTcpServer(port))
{
perror("Opening tcp port failed");
return 1;
}
useTcpIp = 1;
}
int ret = 1;
while (!exitFlag)
{
if (useTcpIp)
{
ret = waitForTcpData(buff, 1);
}
else
{
buff[0] = *commandStr;
commandStr++;
}
if (ret)
{
cbuff = nbuff;
switch (buff[0])
{
case 'c':
if (captureImage(fd, buffers[cbuff], buffSize * sizeof(imageBuffer)))
return 1;
printOut("#image captured\n");
break;
case 'n':
nbuff = !cbuff;
normalizeImage(buffers[cbuff], buffers[nbuff]); //0.2 ms
printOut("#image normalized\n");
break;
case 'g':
gausFilter(buffers[cbuff], buffers[!cbuff]); // 14 ms
printOut("#gaus filter applied\n");
break;
case 'e':
nbuff = !cbuff;
sobelFilter(buffers[cbuff], buffers[nbuff]); //14 ms
printOut("#edges detection by sobel filter applied\n");
break;
case 'x':
nbuff = !cbuff;
nonMaximumSuppression(buffers[cbuff], buffers[nbuff], 128); //9 ms
printOut("#non-edges removed\n");
break;
case 'M':
nbuff = !cbuff;
clearBuffer(buffers[nbuff]); //1.5 ms
houghTransformMiniscus(buffers[cbuff], buffers[nbuff]); //36 ms with sqrt
printOut("#miniscus hough transformed\n");
break;
case 'L':
nbuff = !cbuff;
clearBuffer(buffers[nbuff]); //1.5 ms
houghTransformLines(buffers[cbuff], buffers[nbuff]);
printOut("#line hough transformed\n");
break;
case 'H':
nbuff = !cbuff;
clearBuffer(buffers[nbuff]); //1.5 ms
houghTransformHorizontalLines(buffers[cbuff], buffers[nbuff]);
printOut("#horizontal lines hough transformed\n");
break;
case 'V':
nbuff = !cbuff;
clearBuffer(buffers[nbuff]); //1.5 ms
houghTransformVerticalLines(buffers[cbuff], buffers[nbuff]);
printOut("#vertical lines hough transformed\n");
break;
case 'C':
nbuff = !cbuff;
clearBuffer(buffers[nbuff]); //1.5 ms
houghTransformCircles(buffers[cbuff], buffers[nbuff]);
printOut("#circle hough transformed\n");
break;
case 'm':
nbuff = !cbuff;
findMaxima(buffers[cbuff], buffers[nbuff], 0x10000 / 5, 32); // 0.5 ms
printOut("#non-maxima pixels removed\n");
break;
case 'b':
binarize(buffers[cbuff], buffers[cbuff], 0x10000 / 2); //0.2 ms
printOut("#image normalized\n");
break;
case 'o':
nbuff = !cbuff;
convertToSlope(buffers[cbuff], buffers[nbuff]); //0.2 ms
printOut("#converted to slope\n");
break;
case 'l':
itemCount = getPixelList(buffers[cbuff], buffers[cbuff], maxima, maxNumb);
printOut("#pixel list: (x y value)\n");
for (int i = 0; i < itemCount; i++)
{
numberToString(maxima[i].x, 0);
printOutChar(' ');
numberToString(maxima[i].y, 0);
printOutChar(' ');
numberToString(maxima[i].value[4], 0);
printOutChar('\n');
}
if (useTcpIp) sendTcpData("\n", 1);
printOut("#end of list\n");
break;
case 'p':
itemCount = getPixelList(buffers[cbuff], buffers[!cbuff], maxima, maxNumb);
printOut("#pixel list: (x y value)\n");
for (int i = 0; i < itemCount; i++)
{
numberToString(maxima[i].x, 0);
printOutChar(' ');
numberToString(maxima[i].y, 0);
for (j = 0; j < 9; j++)
{
printOutChar(' ');
numberToString(maxima[i].value[j], 0);
}
printOutChar('\n');
}
if (useTcpIp) sendTcpData("\n", 1);
printOut("#end of list\n");
break;
case 'w':
if (fnIncrPos > -1) filePath[fnIncrPos] = fnIncr + 48;
if (write16BitTiff(buffers[cbuff], crcap.bounds.width, crcap.bounds.height, filePath))
printOut("#image written\n");
else
printOut("#error open file\n");
fnIncr++;
if (fnIncr > 9) fnIncr = 0;
break;
case 's':
//swap current buffer with storage buffer (buffer 2)
tmpib = buffers[2];
buffers[2] = buffers[nbuff];
buffers[nbuff] = tmpib;
nbuff = 2;
printOut("#image data stored\n");
break;
case 'r':
nbuff = 2;
printOut("#image data recalled\n");
break;
case 'q':
nbuff = 2;
printOut("#close socket\n");
closeTcpConnection();
break;
case 'Q':
printOut("#quit application\n");
exitFlag = 1;
break;
case 'z':
fnIncr = 0;
printOut("#reset index to zero\n");
break;
case 'i':
tcpsilent = 0;
printOut("#show info and results over tcp/ip\n");
break;
case 'd':
tcpsilent = 1;
printOut("#show only results over tcp/ip\n");
break;
case 0:
//end of -c command parameter
exitFlag = 1;
break;
default:
if (buff[0] > 32)
printOut("#unknown command\n");
}
}
}
if (useTcpIp)
{
closeTcpConnection();
close(fd);
}
if (!silent) printf("quit program\n");
return 0;
}

View File

@ -1,515 +0,0 @@
#include <stdio.h>
#include "imageRec.h"
const short sobelFilterKernel[3][3] = { { 3, 10, 3 }, { 0, 0, 0 }, { -3, -10, -3 } };
const imageBuffer gausFilterKernel[5] = { 25, 61, 83, 61, 25 };
int imageWidth = 0;
int imageHight = 0;
int imageBufferSize = 0;
int setImageSize(int width, int hight)
{
imageWidth = width;
imageHight = hight;
imageBufferSize = width * hight;
return imageBufferSize;
}
void normalizeImage(imageBuffer* srcImage, imageBuffer* dstImage)
{
int min = 0xFFFF;
int max = 0;
unsigned int factor;
for (int i = 0; i < imageBufferSize; i++)
{
if (srcImage[i] < min) min = srcImage[i];
if (srcImage[i] > max) max = srcImage[i];
}
factor = (1 << 30) / (max - min + 1);
for (int i = 0; i < imageBufferSize; i++)
{
dstImage[i] = (imageBuffer)((srcImage[i] - min) * factor / (1<<14));
}
}
void gausFilter(imageBuffer * image, imageBuffer * helperImage)
{
int n = sizeof(gausFilterKernel) / sizeof(gausFilterKernel[0]);
int acc;
int acck = 0;
int i = 0;
for (int y = 0; y < imageHight; y++)
{
for (int x = 0; x < imageWidth; x++)
{
acc = 0;
acck = 0;
for (int j = 0; j < n; j++)
{
int pos = x + j - n / 2;
if (pos >= 0 && pos < imageWidth)
{
acc += image[i + j - n / 2] * gausFilterKernel[j];
acck += gausFilterKernel[j];
}
}
helperImage[i] = (unsigned short)(acc / acck);
i++;
}
}
i = 0;
for (int y = 0; y < imageHight; y++)
{
for (int x = 0; x < imageWidth; x++)
{
acc = 0;
acck = 0;
for (int j = 0; j < n; j++)
{
int pos = y + j - n / 2;
if (pos >= 0 && pos < imageHight)
{
acc += helperImage[i + (j - n / 2) * imageWidth] * gausFilterKernel[j];
acck += gausFilterKernel[j];
}
}
image[i] = (unsigned short)(acc / acck);
i++;
}
}
}
int getX(imageBuffer combinedXy)
{
return (combinedXy & 0xFF) - 0x80;
}
int getY(imageBuffer combinedXy)
{
return (combinedXy / 0x100) - 0x80;
}
void sobelFilter(imageBuffer * srcImage, imageBuffer * dstImage)
{
int i = 0;
for (int y = 0; y < imageHight; y++)
{
for (int x = 0; x < imageWidth; x++)
{
int dx = 0;
int dy = 0;
if (x > 0 && x < imageWidth - 1 && y > 0 && y < imageHight - 1)
{
for (int ix = 0; ix < 3; ix++)
{
for (int iy = 0; iy < 3; iy++)
{
int srcVal = srcImage[(x + ix - 1) + (y + iy - 1) * imageWidth];
dx += srcVal * sobelFilterKernel[ix][iy];
dy += srcVal * sobelFilterKernel[iy][ix];
}
}
dx /= 0x800;
dy /= 0x800;
if (dx > 127) dx = 127;
if (dx < -128) dx = -128;
if (dy > 127) dy = 127;
if (dy < -128) dy = -128;
//dstImage[i] = combineXy(dx,dy);
dstImage[i] = (unsigned short)(dx + 0x80 + (dy + 0x80) * 0x100);
}
else
{
dstImage[i] = 0x8080;
}
i++;
}
}
}
int getSlope(imageBuffer value)
{
int dy = (value / 0x100) - 0x80;
int dx = (value & 0xFF) - 0x80;
return (dx * dx + dy * dy);
}
//srcImage must be a result from sobelFilter
void nonMaximumSuppression(imageBuffer * srcImage, imageBuffer * dstImage, int minSlope)
{
int i = 0;
int slope;
for (int y = 0; y < imageHight; y++)
{
for (int x = 0; x < imageWidth; x++)
{
if (x > 0 && x < imageWidth - 1 && y > 0 && y < imageHight - 1)
{
slope = getSlope(srcImage[i]);
if (slope < minSlope)
{
dstImage[i] = 0x8080;
}
else
{
int count = 0;
if (getSlope(srcImage[i - 1 - imageWidth]) > slope) count++;
if (getSlope(srcImage[i - 0 - imageWidth]) > slope) count++;
if (getSlope(srcImage[i + 1 - imageWidth]) > slope) count++;
if (getSlope(srcImage[i - 1]) > slope) count++;
if (getSlope(srcImage[i + 1]) > slope) count++;
if (getSlope(srcImage[i - 1 + imageWidth]) > slope) count++;
if (getSlope(srcImage[i - 0 + imageWidth]) > slope) count++;
if (getSlope(srcImage[i + 1 + imageWidth]) > slope) count++;
if (count > 2)
dstImage[i] = 0x8080;
else
dstImage[i] = srcImage[i];
}
}
else
{
dstImage[i] = 0x8080;
}
i++;
}
}
}
/*void drawLine(imageBuffer* dstImage, int x0, int y0, int x1, int y1)
{
int x = x0;
int y = y0;
int dx = x1 - x0;
int dy = y1 - y0;
int err = dx + dy, e2; // error value e_xy
while (true)
{
dstImage[y * IMAGE_WIDTH + x] += 1;// 64 + cr;
if (x == x1 && y == y1) break;
e2 = 2 * err;
if (e2 > dy) { err += dy; x++; }
if (e2 < dx) { err += dx; y++; }
}
}*/
void houghTransformCircles(imageBuffer * srcImage, imageBuffer * dstImage)
{
int i = 0;
int xslope, yslope;
for (int y = 0; y < imageHight; y++)
{
for (int x = 0; x < imageWidth; x++)
{
if (srcImage[i] != 0x8080)
{
xslope = getX(srcImage[i]);
yslope = getY(srcImage[i]);
if (xslope * xslope > yslope * yslope)
{
for (int xi = 0; xi < imageWidth; xi++)
{
int yi = (xi - x) * yslope / xslope + y;
if (yi > 0 && yi < imageHight)
dstImage[yi * imageWidth + xi]++;
}
}
else
{
for (int yi = 0; yi < imageHight; yi++)
{
int xi = (yi - y) * xslope / yslope + x;
if (xi > 0 && xi < imageWidth)
dstImage[yi * imageWidth + xi]++;
}
}
}
i++;
}
}
}
void intenerlal_houghTransformLines(imageBuffer * srcImage, imageBuffer * dstImage, int filter)
{
int i = 0;
const int cx = imageWidth / 2;
const int cy = imageHight / 2;
for (int y = 0; y < imageHight; y++)
{
for (int x = 0; x < imageWidth; x++)
{
if (srcImage[i] != 0x8080)
{
int xslope = getX(srcImage[i]);
int yslope = getY(srcImage[i]);
int xslope2 = xslope * xslope;
int yslope2 = yslope * yslope;
if (filter == 0 || (filter == 1 && yslope2 > xslope2) || (filter == 2 && yslope2 < xslope2))
{
int inter = ((x - cx) * xslope + (y - cy) * yslope) * 0x100 / (xslope2 + yslope2);
int htx = cx + inter * xslope / 0x100;
int hty = cy + inter * yslope / 0x100;
if (htx > 0 && htx < imageWidth && hty > 0 && hty < imageHight && dstImage[hty * imageWidth + htx] < 0xFFFF)
dstImage[hty * imageWidth + htx] ++;
//std::cout << htx << " " << hty << " - " << xslope << " " << yslope << " " << ".\n";
//printf("%i %i %i %i\n", htx, hty, xslope, yslope);
}
}
i++;
}
}
}
void houghTransformLines(imageBuffer* srcImage, imageBuffer* dstImage)
{
intenerlal_houghTransformLines(srcImage, dstImage, 0);
}
void houghTransformVerticalLines(imageBuffer* srcImage, imageBuffer* dstImage)
{
intenerlal_houghTransformLines(srcImage, dstImage, 2);
}
void houghTransformHorizontalLines(imageBuffer* srcImage, imageBuffer* dstImage)
{
intenerlal_houghTransformLines(srcImage, dstImage, 1);
}
static int usqrt4(int val) {
int a, b;
a = 256; // starting point is relatively unimportant
b = val / a; a = (a + b) / 2;
b = val / a; a = (a + b) / 2;
b = val / a; a = (a + b) / 2;
b = val / a; a = (a + b) / 2;
b = val / a; a = (a + b) / 2;
return a;
}
void houghTransformMiniscus(imageBuffer * srcImage, imageBuffer * dstImage)
{
int i = 0;
for (int y = 0; y < imageHight; y++)
{
for (int x = 0; x < imageWidth; x++)
{
if (srcImage[i] != 0)
{
int xslope = getX(srcImage[i]);
int yslope = getY(srcImage[i]);
if (xslope != 0)
{
int preCalc = 0x1000 * yslope / xslope;
for (int htx = 0; htx < imageWidth; htx++)
{
int dx = htx - x;
//int dy = dx * yslope / xslope;
int dy = dx * preCalc / 0x1000;
if (dx != 0)
{
int r = usqrt4(dx * dx + dy * dy);
//int r = sqrt(dx * dx + dy * dy);
int hty = y + dy - r;
if (hty >= 0 && hty < imageHight)
dstImage[hty * imageWidth + htx] ++;
}
}
}
}
i++;
}
}
}
void findMaxima(imageBuffer* srcImage, imageBuffer* dstImage, int threshold, int minDistance)
{
int ws2 = minDistance / 2;
int maxVal;
int maxInd;
for (int i = 0; i < imageBufferSize; i++)
{
dstImage[i] = srcImage[i];
}
for (int y = ws2; y < imageHight; y += ws2)
{
for (int x = ws2; x < imageWidth; x += ws2)
{
maxVal = threshold;
maxInd = -1;
for (int ix = -ws2; ix < ws2; ix++)
{
for (int iy = -ws2; iy < ws2; iy++)
{
int i = (x + ix) + (y + iy) * imageWidth;
if (srcImage[i] > maxVal)
{
maxInd = i;
maxVal = srcImage[i];
}
}
}
for (int ix = -ws2; ix < ws2; ix++)
{
for (int iy = -ws2; iy < ws2; iy++)
{
int i = (x + ix) + (y + iy) * imageWidth;
if (i != maxInd)
dstImage[i] = 0;
}
}
}
}
}
void bubbleSort(struct pixel_list* array, int length)
{
int i, j;
struct pixel_list tmp;
for (i = 1; i < length; i++)
{
for (j = 0; j < length - i; j++)
{
if (array[j].value[4] < array[j + 1].value[4])
{
tmp = array[j];
array[j] = array[j + 1];
array[j + 1] = tmp;
}
}
}
}
int getPixelList(imageBuffer* primImage, imageBuffer* secImage, struct pixel_list* list, int listLenght)
{
int i = 0;
int j = 0;
for (int y = 1; y < imageHight - 1; y++)
{
for (int x = 1; x < imageWidth - 1; x++)
{
i = x + y * imageWidth;
if (primImage[i] != 0 && j < listLenght)
{
list[j].value[0] = secImage[x + (y - 1) * imageWidth - 1];
list[j].value[1] = secImage[x + (y - 1) * imageWidth];
list[j].value[2] = secImage[x + (y - 1) * imageWidth + 1];
list[j].value[3] = secImage[i - 1];
list[j].value[4] = secImage[i];
list[j].value[5] = secImage[i + 1];
list[j].value[6] = secImage[x + (y + 1) * imageWidth - 1];
list[j].value[7] = secImage[x + (y + 1) * imageWidth];
list[j].value[8] = secImage[x + (y + 1) * imageWidth + 1];
list[j].x = x;
list[j].y = y;
j++;
}
i++;
}
}
bubbleSort(list, listLenght);
return j;
}
void convertToSlope(imageBuffer* srcImage, imageBuffer* dstImage)
{
for (int i = 0; i < imageBufferSize; i++)
{
dstImage[i] = (unsigned short)getSlope(srcImage[i]);
}
}
void binarize(imageBuffer * srcImage, imageBuffer * dstImage, int threshold)
{
for (int i = 0; i < imageBufferSize; i++)
{
dstImage[i] = (srcImage[i] > threshold) ? 0xFFFF : 0;
}
}
void clearBufferArea(imageBuffer * dstImage, int startLine, int endLine)
{
for (int i = 0; i < imageBufferSize; i++)
{
if (i / imageWidth >= startLine && i / imageWidth < endLine)
dstImage[i] = 0;
}
}
void clearBuffer(imageBuffer* dstImage)
{
clearBufferArea(dstImage, 0, imageHight);
}