| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- #include "PikaCV_Transforms.h"
- #include "PikaCV_Converter.h"
- #include "PikaCV_Filter.h"
- #include "PikaCV_common.h"
- #include "math.h"
- void PikaCV_Transforms_rotateDown(PikaObj* self, PikaObj* image) {
- PikaCV_Image* img = obj_getStruct(image, "image");
- if (NULL == img) {
- pika_assert(0);
- return;
- }
- if ((img->format != PikaCV_ImageFormat_Type_BGR888) &&
- (img->format != PikaCV_ImageFormat_Type_RGB888)) {
- obj_setErrorCode(self, PIKA_RES_ERR_OPERATION_FAILED);
- obj_setSysOut(self, "unsupported image format");
- return;
- }
- int width = img->width;
- int height = img->height;
- int size_new = width * height * 3;
- Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
- uint8_t* data = _image_getData(image);
- uint8_t* data_new = arg_getBytes(arg_data_new);
- int i, j, k;
- /* rotate */
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- for (k = 0; k < 3; k++) {
- data_new[(height - i - 1) * width * 3 + j * 3 + k] =
- data[i * width * 3 + j * 3 + k];
- }
- }
- }
- obj_setBytes(image, "_data", data_new, size_new);
- img->size = size_new;
- arg_deinit(arg_data_new);
- }
- void PikaCV_Transforms_threshold(PikaObj* self,
- PikaObj* image,
- int maxval,
- int thre,
- int thresholdType) {
- PikaCV_Image* src = obj_getStruct(image, "image");
- if (NULL == src) {
- pika_assert(0);
- return;
- }
- PikaCV_Format_Check(image, PikaCV_ImageFormat_Type_GRAY,
- PikaCV_Check_Converter);
- uint8_t* src_data = _image_getData(image);
- int i;
- if (thresholdType == 0) {
- for (i = 0; i < (src->size); i++) {
- src_data[i] = src_data[i] > thre ? maxval : 0;
- }
- } else if (thresholdType == 1) {
- for (i = 0; i < (src->size); i++) {
- src_data[i] = src_data[i] > thre ? 0 : maxval;
- }
- } else if (thresholdType == 2) {
- for (i = 0; i < (src->size); i++) {
- src_data[i] = src_data[i] > thre ? thre : src_data[i];
- }
- } else if (thresholdType == 3) {
- for (i = 0; i < (src->size); i++) {
- src_data[i] = src_data[i] > thre ? src_data[i] : 0;
- }
- } else if (thresholdType == 4) {
- for (i = 0; i < (src->size); i++) {
- src_data[i] = src_data[i] > thre ? 0 : src_data[i];
- }
- } else if (thresholdType == 5) {
- PikaCV_Transforms_setOTSU(self, image);
- } else {
- pika_assert(0);
- return;
- }
- obj_setBytes(image, "_data", src_data, src->size);
- }
- void PikaCV_Transforms_setROI(PikaObj* self,
- PikaObj* image,
- int x,
- int y,
- int w,
- int h) {
- PikaCV_Image* src = obj_getStruct(image, "image");
- int width = src->width;
- int height = src->height;
- if (NULL == src) {
- pika_assert(0);
- return;
- }
- PikaCV_Format_Check(image, PikaCV_ImageFormat_Type_RGB888,
- PikaCV_Check_Converter);
- if (x <= 0 || y <= 0 || w <= 0 || h <= 0) {
- pika_assert(0);
- return;
- }
- if (x + w > width || y + h > height) {
- pika_assert(0);
- return;
- }
- int size_new = h * w * 3;
- Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
- uint8_t* data = _image_getData(image);
- uint8_t* data_new = arg_getBytes(arg_data_new);
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- data_new[i * 3 * w + j * 3] =
- data[(i + y - 1) * width * 3 + (j + x - 1) * 3];
- data_new[i * 3 * w + j * 3 + 1] =
- data[(i + y - 1) * width * 3 + (j + x - 1) * 3 + 1];
- data_new[i * 3 * w + j * 3 + 2] =
- data[(i + y - 1) * width * 3 + (j + x - 1) * 3 + 2];
- }
- }
- src->height = h;
- src->width = w;
- src->size = size_new;
- obj_setBytes(image, "_data", data_new, size_new);
- arg_deinit(arg_data_new);
- }
- int PikaCV_Transforms_getOTSUthre(PikaObj* self, PikaObj* image) {
- PikaCV_Image* src = obj_getStruct(image, "image");
- if (NULL == src) {
- pika_assert(0);
- return 0;
- }
- PikaCV_Format_Check(image, PikaCV_ImageFormat_Type_GRAY,
- PikaCV_Check_Converter);
- const int Grayscale = 256;
- int width = src->width;
- int height = src->height;
- int size = src->size;
- int threshold = 0;
- int graynum[256] = {0};
- uint8_t* data = _image_getData(image);
- for (int i = 0; i < size; i++) {
- graynum[data[i]]++;
- }
- pika_float P[256] = {0.0};
- pika_float PK[256] = {0.0};
- pika_float MK[256] = {0.0};
- pika_float srcpixnum = width * height, sumtmpPK = 0, sumtmpMK = 0;
- for (int i = 0; i < Grayscale; ++i) {
- P[i] = graynum[i] / srcpixnum;
- PK[i] = sumtmpPK + P[i];
- sumtmpPK = PK[i];
- MK[i] = sumtmpMK + i * P[i];
- sumtmpMK = MK[i];
- }
- pika_float Var = 0;
- for (int k = 0; k < Grayscale; ++k) {
- if (PK[k] > 0.0) {
- pika_float t = MK[Grayscale - 1] * PK[k] - MK[k];
- pika_float w = PK[k] * (1 - PK[k]);
- pika_float variance = t * t / w;
- if (variance > Var) {
- Var = variance;
- threshold = k;
- }
- }
- }
- return threshold;
- }
- void PikaCV_Transforms_setOTSU(PikaObj* self, PikaObj* image) {
- PikaCV_Image* src = obj_getStruct(image, "image");
- if (NULL == src) {
- pika_assert(0);
- return;
- }
- PikaCV_Format_Check(image, PikaCV_ImageFormat_Type_GRAY,
- PikaCV_Check_Converter);
- int thre = PikaCV_Transforms_getOTSUthre(self, image);
- uint8_t* src_data = _image_getData(image);
- int i;
- for (i = 0; i < (src->size); i++) {
- src_data[i] = src_data[i] > thre ? 255 : 0;
- }
- obj_setBytes(image, "_data", src_data, src->size);
- }
- #define MAX(a, b) ((a) > (b) ? (a) : (b))
- #define MIN(a, b) ((a) < (b) ? (a) : (b))
- void PikaCV_Transforms_resize(PikaObj* self,
- PikaObj* image,
- int x,
- int y,
- int resizeType) {
- PikaCV_Image* src = obj_getStruct(image, "image");
- int width = src->width;
- int height = src->height;
- if (NULL == src) {
- pika_assert(0);
- return;
- }
- if (x <= 0 || y <= 0) {
- pika_assert(0);
- return;
- }
- PikaCV_Format_Check(image, PikaCV_ImageFormat_Type_RGB888,
- PikaCV_Check_Converter);
- int size_new = x * y * 3;
- Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
- uint8_t* data = _image_getData(image);
- uint8_t* data_new = arg_getBytes(arg_data_new);
- pika_float scale_x = (pika_float)width / (pika_float)x;
- pika_float scale_y = (pika_float)height / (pika_float)y;
- if (resizeType == 0) {
- for (int i = 0; i < y; ++i) {
- int sy = floor(i * scale_y);
- sy = MIN(sy, (height - 1));
- for (int j = 0; j < x; ++j) {
- int sx = floor(j * scale_x);
- sx = MIN(sx, (width - 1));
- data_new[i * x * 3 + j * 3] = data[sy * width * 3 + sx * 3];
- data_new[i * x * 3 + j * 3 + 1] =
- data[sy * width * 3 + sx * 3 + 1];
- data_new[i * x * 3 + j * 3 + 2] =
- data[sy * width * 3 + sx * 3 + 2];
- }
- }
- } else {
- pika_assert(0);
- return;
- }
- src->height = y;
- src->width = x;
- src->size = size_new;
- obj_setBytes(image, "_data", data_new, size_new);
- arg_deinit(arg_data_new);
- }
- void PikaCV_Transforms_adaptiveThreshold(PikaObj* self,
- PikaObj* image,
- int maxval,
- int subsize,
- int c,
- int method) {
- PikaCV_Image* src = obj_getStruct(image, "image");
- if (NULL == src) {
- pika_assert(0);
- return;
- }
- if (c < 0 || c > 255) {
- pika_assert(0);
- return;
- }
- PikaCV_Format_Check(image, PikaCV_ImageFormat_Type_GRAY,
- PikaCV_Check_Converter);
- int size = src->size;
- uint8_t* src_data = _image_getData(image);
- uint8_t* src_copy;
- src_copy = (uint8_t*)calloc(size, 1);
- memcpy(src_copy, src_data, size);
- if (method == 0) {
- PikaCV_Filter_meanFilter(self, image, subsize, subsize);
- } else if (method == 1) {
- PikaCV_Filter_medianFilter(self, image);
- } else {
- free(src_copy);
- return;
- }
- /* update size after filter */
- size = src->size;
- uint8_t* smooth_data = _image_getData(image);
- for (int i = 0; i < size; i++) {
- uint8_t result = smooth_data[i] - (uint8_t)c;
- smooth_data[i] =
- ((result < MIN(smooth_data[i], (uint8_t)c)) ? 0 : result);
- }
- for (int i = 0; i < size; i++) {
- src_copy[i] = ((src_copy[i] > smooth_data[i]) ? (uint8_t)maxval : 0);
- }
- obj_setBytes(image, "_data", src_copy, size);
- free(src_copy);
- }
- #undef MAX
- #undef MIN
|