mirror of https://github.com/Nonannet/pelfy.git
New test obj files generated
This commit is contained in:
parent
7bd2bf4602
commit
c743403969
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
Loading…
Reference in New Issue