12/09/2018

Table(grid) detector


Table(grid) detector source code.
The code find table row & col lines in document image.

Output




Table(Grid) Detector
buy : https://www.cvlecture.marearts.com/product-page/table-grid-detector
test : http://www.marearts.com/webapp/dtable/
github : https://github.com/MareArts/DTable

Usage source code
#include "DTable.h"

//for local computer
void main()
{

    CDTable cDT;

    //test image
    char str[255];
    for (int i = 0; i < 10; ++i)
    {
        
        //make file string
        sprintf_s(str, "%d.jpg", i + 1);
        printf("%s open \n", str);

        //read
        Mat oimg = imread(str);

        //check
        if (oimg.empty())
            continue;

        //get rect vector
        vector< GridV> vRect;
        //dtable
        if (cDT.FindGrid(oimg, vRect, 0, 0) == false)
        {
            printf("Couldn't Find \n");
            break;
        }


        //show table
        namedWindow("oimg", 0);
        int idx = 0;
        for (auto it : vRect)
        {

            printf("%d grid :  (x:%d, y:%d, width:%d, height:%d \n", idx, it.rect.x, it.rect.y, it.rect.width, it.rect.height);

            if (it.pure)
                cv::rectangle(oimg, it.rect, CV_RGB(0, 255, 0), 2);
            else
                cv::rectangle(oimg, it.rect, CV_RGB(255, 0, 0), 2);

            idx++;
        }

        vRect.clear();

        //exit
        imshow("oimg", oimg);
        if (waitKey(0) == 'q')
        {
            break;
        }
    }

    destroyAllWindows();
    
}

11/18/2018

Elastic image effect, python opencv example source code.

Elastic effect source code.
It can be useful when you want to augment image dataset.
and it is also good to make image effect.

Please refer code:

import numpy as np
import cv2
from scipy.ndimage.interpolation import map_coordinates
from scipy.ndimage.filters import gaussian_filter

def elastic(image, alpha, sigma, random_state=None):
"""Elastic deformation of images as described in [Simard2003]_.
.. [Simard2003] Simard, Steinkraus and Platt, "Best Practices for
Convolutional Neural Networks applied to Visual Document Analysis", in
Proc. of the International Conference on Document Analysis and
Recognition, 2003.
"""
if random_state is None:
random_state = np.random.RandomState(None)

#print(random_state)
shape = image.shape
dx = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
dy = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma, mode="constant", cval=0) * alpha
dz = np.zeros_like(dx)

x, y, z = np.meshgrid(np.arange(shape[1]), np.arange(shape[0]), np.arange(shape[2]))

indices = np.reshape(y+dy, (-1, 1)), np.reshape(x+dx, (-1, 1)), np.reshape(z, (-1, 1))
distored_image = map_coordinates(image, indices, order=1, mode='nearest') #wrap,reflect, nearest

return distored_image.reshape(image.shape)



#main
#file read
o_img = cv2.imread('izone_oy.png')
elMat = elastic(o_img, alpha=5000, sigma=8, random_state=None)

cv2.namedWindow('origin',0)
cv2.imshow('origin', o_img)
cv2.namedWindow('elastic',0)
cv2.imshow('elastic', elMat)

cv2.waitKey(0)


GitHub url :



python OpenCV, draw grid example source code

make well divided linear coordinate
And make pair coordinate

Please see code for detail explanation.


import numpy as np
import cv2
import sys

rows = 500
cols = 500
newMat_3ch = np.zeros((rows, cols, 3), dtype = "uint8") #3channel

step = 20
x = np.linspace(start=0, stop=rows, num=step)
y = np.linspace(start=0, stop=cols, num=step)

v_xy = []
h_xy = []
for i in range(step):
v_xy.append( [int(x[i]), 0, int(x[i]), rows-1] )
h_xy.append( [0, int(y[i]), cols-1, int(y[i])] )

for i in range(step):
[x1, y1, x2, y2] = v_xy[i]
[x1_, y1_, x2_, y2_] = h_xy[i]

cv2.line(newMat_3ch, (x1,y1), (x2, y2), (0,0,255),1 )
cv2.line(newMat_3ch, (x1_,y1_), (x2_, y2_), (255,0,0),1 )
cv2.namedWindow('newMat_3ch',0)
cv2.imshow('newMat_3ch', newMat_3ch)
cv2.waitKey(0)




11/15/2018

data dump by pickle in python

Data dump by pickle

see below example:

data dump to file 
import pickle
f = open("any_file.dmp', "wb")
f.write(pickle.dumps(data))
f.close()

data load by dump
data = pickle.loads(open("any_file.dmp", "rb").read())




11/13/2018

_mask.so : undefined symbol: _Py_ZeroStruct


>git clone https://github.com/cocodataset/cocoapi.git
>cd cocoapi/PythonAPI
>sudo make
*** python 2.7
>python setup.py build_ext install
***python 3.x
>python3 setup.py build_ext install
>cp -r pycocotools <path_to_tensorflow>/models/research/


11/09/2018

How to mount extra hdd permanently

> sudo -I blkid
/dev/sdb1: UUID="0687f976-6efe-4ac5-88dd-8fd863f8b8bf" TYPE="ext4" PARTUUID="1569f982-01"/dev/sda1: LABEL="cloudimg-rootfs" UUID="8ae3d910-2d2a-492d-8667-d0fa24e4d357" TYPE="ext4" PARTUUID="05ae307a-01"/dev/sdc1: UUID="e8abbf34-2cb2-471f-bac6-2a5caec81ad8" TYPE="ext4" PARTUUID="4c4db30a-01"




check uuid that you want to mount
>sudo nano /etc/fstab
Add this string end of file, but uuid must be your value, and ext4 also should be same with blkid information

UUID=e8abbf34-2cb2-471f-bac6-2a5caec81ad8 /media/datadisk ext4 defults,nofail    0       2

Thank you.



11/04/2018

OpenCV python, SuperPixel example source code. (usage of createSuperpixelSEEDS)

input image



output image

 
 


source code

import cv2 as cv
import numpy as np
import sys
import random


#read image
img = cv.imread('izone_oy.png')
converted_img = cv.cvtColor(img, cv.COLOR_BGR2HSV)

height,width,channels = converted_img.shape
num_iterations = 6
prior = 2
double_step = False
num_superpixels = 200
num_levels = 4
num_histogram_bins = 5

seeds = cv.ximgproc.createSuperpixelSEEDS(width, height, channels, num_superpixels, num_levels, prior, num_histogram_bins)
color_img = np.zeros((height,width,3), np.uint8)
color_img[:] = (0, 0, 255)
seeds.iterate(converted_img, num_iterations)

# retrieve the segmentation result
labels = seeds.getLabels()

# labels output: use the last x bits to determine the color
num_label_bits = 2
labels &= (1<<num_label_bits)-1
labels *= 1<<(16-num_label_bits)

mask = seeds.getLabelContourMask(False)

# stitch foreground & background together
mask_inv = cv.bitwise_not(mask)
result_bg = cv.bitwise_and(img, img, mask=mask_inv)
result_fg = cv.bitwise_and(color_img, color_img, mask=mask)
result = cv.add(result_bg, result_fg)

cv.namedWindow('mask',0)
cv.namedWindow('result_bg',0)
cv.namedWindow('result_fg',0)
cv.namedWindow('result',0)

cv.imshow('mask',mask_inv)
cv.imshow('result_bg',result_bg)
cv.imshow('result_fg',result_fg)
cv.imshow('result',result)

cv.imwrite('mask.jpg',mask_inv)
cv.imwrite('result_bg.jpg',result_bg)
cv.imwrite('result_fg.jpg',result_fg)
cv.imwrite('result.jpg',result)

cv.waitKey(0)


reference
https://docs.opencv.org/3.0-beta/modules/ximgproc/doc/superpixels.html
https://github.com/opencv/opencv_contrib/blob/master/samples/python2/seeds.py




TypeError: Incorrect type of self (must be 'Feature2D' or its derivative), FastFeatureDetector

This is because of opencv version difference.
Some function is changed as XX_create().
Refer to below code. This is case of FastFeatureDetector.
Thank you.

fast = cv2.FastFeatureDetector_create() # <- FastFeatureDetector()
kp = fast.detect(blurGrayMat)

10/30/2018

How to increase the font size of the bounding box in Tensorflow object detection module?

Find "visualization_utils.py"
This exist in "research/object_detection/utils"
And find below code, modify font size.
If it is not working, change path to absolute path.
Or copy font file to project folder.

Thank you.
try:
#font = ImageFont.truetype('arial.ttf', 24)
font = ImageFont.truetype('/Library/Fonts/Arial.ttf', 100) #leon modify
except IOError:
font = ImageFont.load_default()


Font size up


Korean car number plate 822 images data share


Korean car number plate 822 images,
refer to this link:
https://www.amazon.com/clouddrive/share/zT8bgXMGB4m7ex8VMI8Mgibhi6qJYZRcOtnOwYArMgi

Thank you.


pedestrian 29,286 images data

I share pedestrian 29,286 images data.
https://www.amazon.com/clouddrive/share/bp055ddwIp8DSCgTJL9AWeZvqin6gkpoTg8YrM6K4rt

Thank you.



frontal face 4,429 images (size 24 * 24)

Frontal face 4,429 images
Size is 24 x 24

refer to this link:

*If this data have copyright, please inform to me, I will delete ASAP.




Face 2166 image data

I share face image 2,166 data.
I got these data from an website at very long time ago.
So, I don't remember which site.

If this data have copyright, please inform to me. 
I will delete ASAP.

share link here :

Thank you.



 


Image data : background images

This is background images those are 12,439.
I used this images for negative data when I train face detection model.

This is random images and there is no specific object.
So it will be use for background image or negative image.

Share link is here:
https://www.amazon.com/clouddrive/share/vYnNKcwkK987A7fAUuasX0aPmaMt5wKl6ekSk1v6QAR

I hope it help to anyone.
Thank you.

10/29/2018

google object detection api error: ModuleNotFoundError: No module named 'pycocotools’

You might see this error : No module named 'pycocotools’, when you try to start train.
I refer to my solution.
Good luck!

Error:
ModuleNotFoundError: No module named 'pycocotools’

Solution :
git clone https://github.com/cocodataset/cocoapi.git
cd cocoapi/PythonAPI
make

cp -r pycocotools <path_to_object_detection_api>/models/research/


google object detection api error : object_detection/protos/model.proto:12:5: "Ssd" is not defined.

You might meet this error : "object_detection/protos/model.proto:12:5: "Ssd" is not defined.", when you try below command.

# From tensorflow/models/research/
protoc object_detection/protos/*.proto --python_out=.


I solved this error to use below work.

# Make sure you grab the latest version
curl -OL https://github.com/google/protobuf/releases/download/v3.2.0/protoc-3.2.0-linux-x86_64.zip 

# Unzip 
unzip protoc-3.2.0-linux-x86_64.zip -d protoc3 

# Move protoc to /usr/local/bin/ 
sudo mv protoc3/bin/* /usr/local/bin/ 

# Move protoc3/include to /usr/local/include/ 
sudo mv protoc3/include/* /usr/local/include/ 

# Optional: change owner 
sudo chwon [user] /usr/local/bin/protoc 
sudo chwon -R [user] /usr/local/include/google 


refer to this url:

10/28/2018

python make folder (create directory)

import os

makeFolder = 'folderName'
if not os.path.exists(makeFolder): #if not exist
os.makedirs(makeFolder) #make folder

vs code auto indentations


On Windows Shift + Alt + F
On Mac Shift + Option + F
On Ubuntu Ctrl + Shift +

python pandas, shuffle

refer to example code:



from sklearn.utils import shuffle
import pandas as pd

df = pd.read_csv('test.csv')
df = shuffle(df) #suffle
df.reset_index(drop=True) #index reset
df.to_csv('rfine_table_shuffle.csv', index=False)

10/27/2018

Python String handling tip, remove specific character forward and backward in string

So, this is example code for this processing

input string
__A b c_D___

output string
A b c_D

'_' character is removed in forward and backward.

Refer to code. 🤘
Thank you.

testStr = [' Abc ', ' ', ' ', 'A bc', 'A bc ', ' ', ' a 12 43', ' da ', ' ', 'a2 34', ' 1 2 ']
testStr2 = ['___Abc__', '_', '__', 'A_bc', 'A_bc_', '_____', '_a_12_43', '_da____', '__', 'a2_34', '_1_2_']

def removeTFoward(str, T):
if len(str) == 0:
return str
if str[0] == T:
return removeTFoward(str[1:],T)
else:
return str

def removeTBackword(str, T):
if len(str) == 0:
return str
if str[-1] == T:
return removeTBackword(str[:-1],T)
else:
return str

for n, v in enumerate(testStr2):
str = removeTFoward(v, '_')
str = removeTBackword(str, '_')
if len(str) == 0:
print('nothing')
else:
print(str)


output :
Abc
nothing
nothing
A_bc
A_bc
nothing
a_12_43
da
nothing
a2_34
1_2

10/26/2018

Dithering python opencv source code (Floyd–Steinberg dithering)

This is dithering example, it make image like a stippling effect.


I referenced to blew website.
wiki page:
https://en.wikipedia.org/wiki/Floyd–Steinberg_dithering 
In the source code, there are two functions those are :
dithering_gray, dithering_color
One is for Gary image (1 channel), other is for color (3 channel).
It's very easy to use, just call function~ ^^


import cv2
import numpy as np

def minmax(v):
if v > 255:
v = 255
if v < 0:
v = 0
return v

def dithering_gray(inMat, samplingF):
#https://en.wikipedia.org/wiki/Floyd–Steinberg_dithering
#https://www.youtube.com/watch?v=0L2n8Tg2FwI&t=0s&list=WL&index=151
#input is supposed as color
# grab the image dimensions
h = inMat.shape[0]
w = inMat.shape[1]
# loop over the image
for y in range(0, h-1):
for x in range(1, w-1):
# threshold the pixel
old_p = inMat[y, x]
new_p = np.round(samplingF * old_p/255.0) * (255/samplingF)
inMat[y, x] = new_p
quant_error_p = old_p - new_p

# inMat[y, x+1] = minmax(inMat[y, x+1] + quant_error_p * 7 / 16.0)
# inMat[y+1, x-1] = minmax(inMat[y+1, x-1] + quant_error_p * 3 / 16.0)
# inMat[y+1, x] = minmax(inMat[y+1, x] + quant_error_p * 5 / 16.0)
# inMat[y+1, x+1] = minmax(inMat[y+1, x+1] + quant_error_p * 1 / 16.0)
inMat[y, x+1] = minmax(inMat[y, x+1] + quant_error_p * 7 / 16.0)
inMat[y+1, x-1] = minmax(inMat[y+1, x-1] + quant_error_p * 3 / 16.0)
inMat[y+1, x] = minmax(inMat[y+1, x] + quant_error_p * 5 / 16.0)
inMat[y+1, x+1] = minmax(inMat[y+1, x+1] + quant_error_p * 1 / 16.0)

# quant_error := oldpixel - newpixel
# pixel[x + 1][y ] := pixel[x + 1][y ] + quant_error * 7 / 16
# pixel[x - 1][y + 1] := pixel[x - 1][y + 1] + quant_error * 3 / 16
# pixel[x ][y + 1] := pixel[x ][y + 1] + quant_error * 5 / 16
# pixel[x + 1][y + 1] := pixel[x + 1][y + 1] + quant_error * 1 / 16

# return the thresholded image
return inMat


def dithering_color(inMat, samplingF):
#https://en.wikipedia.org/wiki/Floyd–Steinberg_dithering
#https://www.youtube.com/watch?v=0L2n8Tg2FwI&t=0s&list=WL&index=151
#input is supposed as color
# grab the image dimensions
h = inMat.shape[0]
w = inMat.shape[1]
# loop over the image
for y in range(0, h-1):
for x in range(1, w-1):
# threshold the pixel
old_b = inMat[y, x, 0]
old_g = inMat[y, x, 1]
old_r = inMat[y, x, 2]
new_b = np.round(samplingF * old_b/255.0) * (255/samplingF)
new_g = np.round(samplingF * old_g/255.0) * (255/samplingF)
new_r = np.round(samplingF * old_r/255.0) * (255/samplingF)

inMat[y, x, 0] = new_b
inMat[y, x, 1] = new_g
inMat[y, x, 2] = new_r


quant_error_b = old_b - new_b
quant_error_g = old_g - new_g
quant_error_r = old_r - new_r

inMat[y, x+1, 0] = minmax(inMat[y, x+1, 0] + quant_error_b * 7 / 16.0)
inMat[y, x+1, 1] = minmax(inMat[y, x+1, 1] + quant_error_g * 7 / 16.0)
inMat[y, x+1, 2] = minmax(inMat[y, x+1, 2] + quant_error_r * 7 / 16.0)
inMat[y+1, x-1, 0] = minmax(inMat[y+1, x-1, 0] + quant_error_b * 3 / 16.0)
inMat[y+1, x-1, 1] = minmax(inMat[y+1, x-1, 1] + quant_error_g * 3 / 16.0)
inMat[y+1, x-1, 2] = minmax(inMat[y+1, x-1, 2] + quant_error_r * 3 / 16.0)

inMat[y+1, x, 0] = minmax(inMat[y+1, x, 0] + quant_error_b * 5 / 16.0)
inMat[y+1, x, 1] = minmax(inMat[y+1, x, 1] + quant_error_g * 5 / 16.0)
inMat[y+1, x, 2] = minmax(inMat[y+1, x, 2] + quant_error_r * 5 / 16.0)

inMat[y+1, x+1, 0] = minmax(inMat[y+1, x+1, 0] + quant_error_b * 1 / 16.0)
inMat[y+1, x+1, 1] = minmax(inMat[y+1, x+1, 1] + quant_error_g * 1 / 16.0)
inMat[y+1, x+1, 2] = minmax(inMat[y+1, x+1, 2] + quant_error_r * 1 / 16.0)

# quant_error := oldpixel - newpixel
# pixel[x + 1][y ] := pixel[x + 1][y ] + quant_error * 7 / 16
# pixel[x - 1][y + 1] := pixel[x - 1][y + 1] + quant_error * 3 / 16
# pixel[x ][y + 1] := pixel[x ][y + 1] + quant_error * 5 / 16
# pixel[x + 1][y + 1] := pixel[x + 1][y + 1] + quant_error * 1 / 16

# return the thresholded image
return inMat


#read image
inMat = cv2.imread('iu.jpg') #lena.png')
#color ditering
outMat_color = dithering_color(inMat.copy(), 1)
cv2.imwrite('out_color.jpg', outMat_color)

#gray ditering
grayMat = cv2.cvtColor(inMat, cv2.COLOR_BGR2GRAY)
outMat_gray = dithering_gray(grayMat.copy(), 1)
cv2.imwrite('out_gray.jpg', outMat_gray)




python opencv, example code for image pixel access

The code is example to access every pixel in opencv python.
More detail, just see below code.
Thank you.

import cv2

def OpenCV_Access_RGBValue(inMat):
#input is supposed as color
# grab the image dimensions
h = inMat.shape[0]
w = inMat.shape[1]
# loop over the image
for y in range(0, h):
for x in range(0, w):
# threshold the pixel
b = inMat[y, x, 0]
g = inMat[y, x, 1]
r = inMat[y, x, 2]
b = 255 - b
g = 255 - g
r = 255 - r

inMat[y, x, 0] = b
inMat[y, x, 1] = g
inMat[y, x, 2] = r

#image[y, x] = 255 if image[y, x] >= 128T else 0
# return the thresholded image
return inMat


#read image
inMat = cv2.imread('iu.jpg')

#test value access
OpenCV_Access_RGBValue(inMat)

#display
cv2.namedWindow('test',0)
cv2.imwrite('output.jpg', inMat)
cv2.imshow('test',inMat)
cv2.waitKey(0)






search column name and modify data, python pandas usages


Above all,
Let's make initial column head.

import pandas as pd
#init
col_names = ['product', 'count']
word_pd = pd.DataFrame(columns = col_names)


There is no data yet.
So, let's add initial data

#add produce list
word_pd.loc[len(word_pd)] = ['apple', 4]
word_pd.loc[len(word_pd)] = ['orange', 7]
word_pd.loc[len(word_pd)] = ['beer', 10]
word_pd.loc[len(word_pd)] = ['cola', 7]
word_pd.loc[len(word_pd)] = ['beer', 8]

#check
print('origin data', word_pd)

>
origin data   product count
0   apple     4
1  orange     7
2    beer    10
3    cola     7
4    beer     8


OK, then let's find specific product name and increase count.

#find product
list_pd = word_pd.loc[word_pd['product'] == 'apple']
list_f = list_pd.index.tolist()

#add count
if len(list_f)>0:
for index in list_f:
word_pd.iloc[index][1] = word_pd.iloc[index, word_pd.columns.get_loc('count')] +1

print('result')
print('data', word_pd)

>
result
data   product count
0   apple     5
1  orange     7
2    beer    10
3    cola     7
4    beer     8



OK, at this time, let's find beer product and add count.
Note, there are 2 rows of beer product, so all beer product's count are increased.
#one more test
#find product
list_pd = word_pd.loc[word_pd['product'] == 'beer']
list_f = list_pd.index.tolist()


#add count
if len(list_f)>0:
for index in list_f:
word_pd.iloc[index][1] = word_pd.iloc[index, word_pd.columns.get_loc('count')] +1

print('result')
print('data', word_pd)


result
data   product count
0   apple     5
1  orange     7
2    beer    11
3    cola     7
4    beer     9




This is whole source code.

import pandas as pd
#init
col_names = ['product', 'count']
word_pd = pd.DataFrame(columns = col_names)

#add produce list
word_pd.loc[len(word_pd)] = ['apple', 4]
word_pd.loc[len(word_pd)] = ['orange', 7]
word_pd.loc[len(word_pd)] = ['beer', 10]
word_pd.loc[len(word_pd)] = ['cola', 7]
word_pd.loc[len(word_pd)] = ['beer', 8]

#check
print('origin data', word_pd)

#find product
list_pd = word_pd.loc[word_pd['product'] == 'apple']
list_f = list_pd.index.tolist()

#add count
if len(list_f)>0:
for index in list_f:
word_pd.iloc[index][1] = word_pd.iloc[index, word_pd.columns.get_loc('count')] +1

print('result')
print('data', word_pd)

#one more test
#find product
list_pd = word_pd.loc[word_pd['product'] == 'beer']
list_f = list_pd.index.tolist()


#add count
if len(list_f)>0:
for index in list_f:
word_pd.iloc[index][1] = word_pd.iloc[index, word_pd.columns.get_loc('count')] +1

print('result')
print('data', word_pd)


Thank you.





10/25/2018

ValueError: too many values to unpack (expected 2), when you use "cv2.findContours"

check this tip!

before (error)
contours, _ = cv2.findContours(***, ***, ***)


after (solved)
_, contours, _ = cv2.findContours(***, ***, ***)


10/22/2018

10/17/2018

python float decimal expression (tip)

Tip!

print('{} - {:.4f}'.format(11, 0.12314213))

> 11 - 0.1231



Exclude files that you don't want to show in directory window in VS CODE (The tip for I don't want to see ._* files in vs code)

You can set exclude file pattern in exclude tab in settings.


go to preferences -> settings



find exclude menu and add pattern that you don't want to see.
press 'ok' button and it will work immediately.

Thank you.

10/13/2018