This repository has been archived on 2021-02-05. You can view files and clone it, but cannot push or open issues or pull requests.
ipcv/julia_notebook/assignment.ipynb

444 lines
1.0 MiB
Plaintext
Raw Normal View History

2019-05-14 22:37:19 +07:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"using Images\n",
"using TestImages\n",
"using FileIO\n",
"using Colors\n",
"using ImageFeatures\n",
"using Formatting\n",
"using Plots\n",
"using DSP"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"backwardTransform (generic function with 2 methods)"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function backwardTransform(algo, M, P, outSize=nothing)\n",
" M = inv(M)\n",
" rows, cols = size(P)\n",
" if outSize == nothing\n",
" outSize = size(P)\n",
" end\n",
" out = zeros(eltype(P), outSize)\n",
"\n",
" for index in CartesianIndices(out)\n",
" y, x = Tuple(index)\n",
" sourceIndex = M * [x; y; 1]\n",
" sourceIndex ./= sourceIndex[end]\n",
" x1, y1 = round.(Int32, sourceIndex)\n",
" if (x1 < 1 || y1 < 1 || x1 > cols || y1 > rows)\n",
" continue\n",
" end\n",
" out[index] = P[y1, x1]\n",
" end\n",
" out\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"projectiveTransform (generic function with 1 method)"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function createProjectiveMatrix(points)\n",
" if length(points) != 4\n",
" error(\"Not correct number of point\")\n",
" end\n",
"\n",
" A = zeros(Int64, 2*length(points), 8)\n",
" B = zeros(Int64, 2*length(points), 1)\n",
" for i in 1:length(points)\n",
" x, y, x1, y1 = points[i]\n",
" A[2*i - 1,:] = [x y 1 0 0 0 -x*x1 -x1*y]\n",
" A[2*i,:] = [0 0 0 x y 1 -x*y1 -y*y1]\n",
" B[2*i - 1] = x1\n",
" B[2*i] = y1\n",
" end\n",
"\n",
" H = vcat(A\\B, 1)\n",
" reshape(H, (3,3))'\n",
"end\n",
"\n",
"function projectiveTransform(picture, points, outSize)\n",
" M = createProjectiveMatrix(points)\n",
" backwardTransform(\"zero\", M, picture, outSize)\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"647×1000 Array{RGBA{N0f8},2} with eltype RGBA{Normed{UInt8,8}}:\n",
" RGBA{N0f8}(0.318,0.318,0.329,1.0) … RGBA{N0f8}(0.663,0.627,0.616,1.0)\n",
" RGBA{N0f8}(0.373,0.376,0.365,1.0) RGBA{N0f8}(0.6,0.557,0.533,1.0) \n",
" RGBA{N0f8}(0.373,0.376,0.365,1.0) RGBA{N0f8}(0.6,0.557,0.533,1.0) \n",
" RGBA{N0f8}(0.396,0.396,0.365,1.0) RGBA{N0f8}(0.596,0.561,0.533,1.0)\n",
" RGBA{N0f8}(0.353,0.349,0.337,1.0) RGBA{N0f8}(0.588,0.573,0.545,1.0)\n",
" RGBA{N0f8}(0.349,0.345,0.337,1.0) … RGBA{N0f8}(0.58,0.573,0.541,1.0) \n",
" RGBA{N0f8}(0.349,0.345,0.337,1.0) RGBA{N0f8}(0.58,0.573,0.541,1.0) \n",
" RGBA{N0f8}(0.361,0.349,0.345,1.0) RGBA{N0f8}(0.616,0.58,0.533,1.0) \n",
" RGBA{N0f8}(0.353,0.341,0.341,1.0) RGBA{N0f8}(0.592,0.569,0.51,1.0) \n",
" RGBA{N0f8}(0.361,0.349,0.341,1.0) RGBA{N0f8}(0.58,0.569,0.518,1.0) \n",
" RGBA{N0f8}(0.361,0.349,0.341,1.0) … RGBA{N0f8}(0.58,0.569,0.518,1.0) \n",
" RGBA{N0f8}(0.38,0.365,0.361,1.0) RGBA{N0f8}(0.643,0.6,0.565,1.0) \n",
" RGBA{N0f8}(0.373,0.357,0.357,1.0) RGBA{N0f8}(0.588,0.353,0.369,1.0)\n",
" ⋮ ⋱ \n",
" RGBA{N0f8}(0.678,0.698,0.62,1.0) … RGBA{N0f8}(0.235,0.235,0.239,1.0)\n",
" RGBA{N0f8}(0.686,0.702,0.631,1.0) RGBA{N0f8}(0.247,0.247,0.251,1.0)\n",
" RGBA{N0f8}(0.686,0.702,0.631,1.0) RGBA{N0f8}(0.247,0.247,0.251,1.0)\n",
" RGBA{N0f8}(0.69,0.702,0.639,1.0) RGBA{N0f8}(0.255,0.251,0.255,1.0)\n",
" RGBA{N0f8}(0.678,0.702,0.627,1.0) RGBA{N0f8}(0.247,0.255,0.255,1.0)\n",
" RGBA{N0f8}(0.667,0.694,0.624,1.0) … RGBA{N0f8}(0.239,0.251,0.251,1.0)\n",
" RGBA{N0f8}(0.667,0.694,0.624,1.0) RGBA{N0f8}(0.239,0.251,0.251,1.0)\n",
" RGBA{N0f8}(0.678,0.686,0.647,1.0) RGBA{N0f8}(0.227,0.243,0.247,1.0)\n",
" RGBA{N0f8}(0.482,0.486,0.467,1.0) RGBA{N0f8}(0.231,0.235,0.251,1.0)\n",
" RGBA{N0f8}(0.247,0.251,0.255,1.0) RGBA{N0f8}(0.239,0.239,0.255,1.0)\n",
" RGBA{N0f8}(0.247,0.251,0.255,1.0) … RGBA{N0f8}(0.239,0.239,0.255,1.0)\n",
" RGBA{N0f8}(0.929,0.933,0.945,1.0) RGBA{N0f8}(0.722,0.722,0.733,1.0)"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"source = load(\"../images/bangdiem.png\")\n",
"row, col = size(source)\n",
"points = [\n",
" # [x y x1 y1],\n",
" [14 152 1 1],\n",
" [969 155 col 1],\n",
" [965 637 col row],\n",
" [14 633 1 row]\n",
"]\n",
"\n",
"scanned = projectiveTransform(source, points, size(source))"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"847×1200 Array{RGBA{N0f8},2} with eltype RGBA{Normed{UInt8,8}}:\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" ⋮ ⋱ \n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)"
]
},
"execution_count": 88,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"row, col = size(scanned)\n",
"points = [\n",
" # [x y x1 y1],\n",
" [1 1 200 50],\n",
" [col 1 (col+100) 50],\n",
" [col row (col+200) (row+70)],\n",
" [1 row 55 (row+55)]\n",
"]\n",
"\n",
"raw = projectiveTransform(scanned, points, size(source) .+ 200)"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"histogramMatching (generic function with 1 method)"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function create_cdf(arr)\n",
" hist = zeros(256)\n",
" for val in arr\n",
" val = round(Int32, val)\n",
" hist[val + 1] += 1\n",
" end\n",
" cdf = cumsum(hist)\n",
" cdf ./= length(arr)\n",
" cdf, hist\n",
"end\n",
"\n",
"function histogramMatching(origin_img, prefered_img)\n",
" origin_img_ycbcr = channelview(YCbCr.(origin_img))\n",
" prefered_img_ycbcr = channelview(YCbCr.(prefered_img))\n",
"\n",
" out_img = similar(origin_img)\n",
" out_img_ycbcr = channelview(YCbCr.(out_img))\n",
"\n",
" for c in 1:3\n",
" origin_channel = origin_img_ycbcr[c,:,:]\n",
" prefered_channel = prefered_img_ycbcr[c,:,:]\n",
" \n",
" origin_cdf, origin_hist = create_cdf(origin_channel)\n",
" prefered_cdf, prefered_hist = create_cdf(prefered_channel)\n",
"\n",
" mapping = zeros(256)\n",
" for i in 1:256\n",
" idx = argmin(abs.(prefered_cdf .- origin_cdf[i]))\n",
" mapping[i] = idx - 1\n",
" end\n",
"\n",
" display(mapping)\n",
"\n",
" out_img = out_img_ycbcr[c,:,:]\n",
" for idx in CartesianIndices(out_img)\n",
" old_color = round(Int32,origin_channel[idx])\n",
" new_color = mapping[old_color]\n",
" out_img[idx] = new_color\n",
" end\n",
" end\n",
" out_img\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"256-element Array{Float64,1}:\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" ⋮ \n",
" 235.0\n",
" 235.0\n",
" 235.0\n",
" 235.0\n",
" 235.0\n",
" 235.0\n",
" 235.0\n",
" 235.0\n",
" 235.0\n",
" 235.0\n",
" 235.0\n",
" 235.0"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"256-element Array{Float64,1}:\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" ⋮ \n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"256-element Array{Float64,1}:\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" 0.0\n",
" ⋮ \n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0\n",
" 128.0"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"847×1200 Array{RGBA{N0f8},2} with eltype RGBA{Normed{UInt8,8}}:\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" ⋮ ⋱ \n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) … RGBA{N0f8}(0.0,0.0,0.0,0.0)\n",
" RGBA{N0f8}(0.0,0.0,0.0,0.0) RGBA{N0f8}(0.0,0.0,0.0,0.0)"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bad_raw = histogramMatching(raw, load(\"../images/dark.jpg\"))\n",
"raw"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.2.0-DEV",
"language": "julia",
"name": "julia-1.2"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.2.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}