--- /dev/null
+ 234 235 240 233 240 234 240 235 240 237 240 238 240 240 240 232
+ 229 240 240 240 240 240 240 240 240 240 240 240 240 240 240 228
+ 227 240 240 240 240 240 240 240 240 240 240 240 240 240 240 239
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 231 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 229 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 225 149 240 240 186 216 225 174 240 240 240 237 238 240 240 240
+ 150 107 238 231 75 208 115 147 238 228 223 226 237 180 226 240
+ 150 62 181 213 62 187 113 169 197 72 29 237 120 50 53 207
+ 149 63 47 78 53 184 113 101 142 5 150 150 45 217 186 83
+ 121 84 220 222 58 180 121 92 128 109 237 124 155 232 161 64
+ 149 71 240 240 76 210 98 109 122 108 240 129 51 119 161 155
+ 149 186 240 240 98 219 135 152 207 191 236 227 152 77 175 209
+ 235 235 240 233 240 234 240 235 240 236 240 238 240 240 240 240
+ 229 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 227 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 232 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 229 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 225 156 240 240 186 216 225 186 240 240 240 240 240 240 240 240
+ 150 117 240 231 72 206 115 162 240 232 223 237 240 180 226 240
+ 150 74 187 213 51 184 103 168 197 78 29 237 120 50 53 216
+ 144 77 51 74 61 184 106 101 142 5 150 152 52 217 186 85
+ 117 89 219 219 65 184 121 92 128 100 236 125 156 240 170 73
+ 148 71 240 240 76 210 109 109 121 99 240 137 51 120 166 164
+ 140 186 240 240 98 220 150 156 207 192 236 230 152 77 176 212
+ 234 235 240 233 240 234 240 235 240 236 240 238 240 240 240 233
+ 229 240 240 240 240 240 240 240 240 240 240 240 240 240 240 239
+ 227 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 232 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 235 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 232 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 228 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 225 156 240 240 182 212 225 180 240 240 240 240 240 240 240 240
+ 150 116 238 228 66 205 115 151 238 236 225 240 240 180 226 240
+ 156 84 186 211 47 184 109 170 200 92 30 240 120 50 53 216
+ 147 83 51 73 50 184 106 110 148 17 151 150 45 217 186 85
+ 127 98 219 219 58 179 109 101 128 107 237 125 155 240 163 72
+ 155 86 240 240 76 201 85 108 121 95 232 137 51 118 153 155
+ 149 189 240 240 98 220 141 154 206 178 235 230 152 77 175 209
+
+ 232 228 239 240 240 240 240 240 240 240 240 207 83 64 155 209
+ 240 240 240 240 240 240 240 240 240 240 226 53 186 161 161 175
+ 240 240 240 240 240 240 240 240 240 240 180 50 217 232 119 77
+ 240 240 240 240 240 240 240 240 240 238 237 120 45 155 51 152
+ 238 240 240 240 240 240 240 240 240 237 226 237 150 124 129 227
+ 240 240 240 240 240 240 240 240 240 240 223 29 150 237 240 236
+ 237 240 240 240 240 240 240 240 240 240 228 72 5 109 108 191
+ 240 240 240 240 240 240 240 240 240 240 238 197 142 128 122 207
+ 235 240 240 240 240 240 240 240 240 174 147 169 101 92 109 152
+ 240 240 240 240 240 240 240 240 240 225 115 113 113 121 98 135
+ 234 240 240 240 240 240 240 240 240 216 208 187 184 180 210 219
+ 240 240 240 240 240 240 240 240 240 186 75 62 53 58 76 98
+ 233 240 240 240 240 240 240 240 240 240 231 213 78 222 240 240
+ 240 240 240 240 240 240 240 240 240 240 238 181 47 220 240 240
+ 235 240 240 240 240 240 240 240 240 149 107 62 63 84 71 186
+ 234 229 227 240 236 234 236 231 229 225 150 150 149 121 149 149
+ 240 240 240 240 240 240 240 240 240 240 240 216 85 73 164 212
+ 240 240 240 240 240 240 240 240 240 240 226 53 186 170 166 176
+ 240 240 240 240 240 240 240 240 240 240 180 50 217 240 120 77
+ 240 240 240 240 240 240 240 240 240 240 240 120 52 156 51 152
+ 238 240 240 240 240 240 240 240 240 240 237 237 152 125 137 230
+ 240 240 240 240 240 240 240 240 240 240 223 29 150 236 240 236
+ 236 240 240 240 240 240 240 240 240 240 232 78 5 100 99 192
+ 240 240 240 240 240 240 240 240 240 240 240 197 142 128 121 207
+ 235 240 240 240 240 240 240 240 240 186 162 168 101 92 109 156
+ 240 240 240 240 240 240 240 240 240 225 115 103 106 121 109 150
+ 234 240 240 240 240 240 240 240 240 216 206 184 184 184 210 220
+ 240 240 240 240 240 240 240 240 240 186 72 51 61 65 76 98
+ 233 240 240 240 240 240 240 240 240 240 231 213 74 219 240 240
+ 240 240 240 240 240 240 240 240 240 240 240 187 51 219 240 240
+ 235 240 240 240 240 240 240 240 240 156 117 74 77 89 71 186
+ 235 229 227 240 236 234 236 232 229 225 150 150 144 117 148 140
+ 233 239 240 240 240 240 240 240 240 240 240 216 85 72 155 209
+ 240 240 240 240 240 240 240 240 240 240 226 53 186 163 153 175
+ 240 240 240 240 240 240 240 240 240 240 180 50 217 240 118 77
+ 240 240 240 240 240 240 240 240 240 240 240 120 45 155 51 152
+ 238 240 240 240 240 240 240 240 240 240 240 240 150 125 137 230
+ 240 240 240 240 240 240 240 240 240 240 225 30 151 237 232 235
+ 236 240 240 240 240 240 240 240 240 240 236 92 17 107 95 178
+ 240 240 240 240 240 240 240 240 240 240 238 200 148 128 121 206
+ 235 240 240 240 240 240 240 240 240 180 151 170 110 101 108 154
+ 240 240 240 240 240 240 240 240 240 225 115 109 106 109 85 141
+ 234 240 240 240 240 240 240 240 240 212 205 184 184 179 201 220
+ 240 240 240 240 240 240 240 240 240 182 66 47 50 58 76 98
+ 233 240 240 240 240 240 240 240 240 240 228 211 73 219 240 240
+ 240 240 240 240 240 240 240 240 240 240 238 186 51 219 240 240
+ 235 240 240 240 240 240 240 240 240 156 116 84 83 98 86 189
+ 234 229 227 240 234 232 235 232 228 225 150 156 147 127 155 149
+
+ 209 175 77 152 227 236 191 207 152 135 219 98 240 240 186 149
+ 155 161 119 51 129 240 108 122 109 98 210 76 240 240 71 149
+ 64 161 232 155 124 237 109 128 92 121 180 58 222 220 84 121
+ 83 186 217 45 150 150 5 142 101 113 184 53 78 47 63 149
+ 207 53 50 120 237 29 72 197 169 113 187 62 213 181 62 150
+ 240 226 180 237 226 223 228 238 147 115 208 75 231 238 107 150
+ 240 240 240 238 237 240 240 240 174 225 216 186 240 240 149 225
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 229
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 231
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 239 240 240 240 240 240 240 240 240 240 240 240 240 240 240 227
+ 228 240 240 240 240 240 240 240 240 240 240 240 240 240 240 229
+ 232 240 240 240 238 240 237 240 235 240 234 240 233 240 235 234
+ 212 176 77 152 230 236 192 207 156 150 220 98 240 240 186 140
+ 164 166 120 51 137 240 99 121 109 109 210 76 240 240 71 148
+ 73 170 240 156 125 236 100 128 92 121 184 65 219 219 89 117
+ 85 186 217 52 152 150 5 142 101 106 184 61 74 51 77 144
+ 216 53 50 120 237 29 78 197 168 103 184 51 213 187 74 150
+ 240 226 180 240 237 223 232 240 162 115 206 72 231 240 117 150
+ 240 240 240 240 240 240 240 240 186 225 216 186 240 240 156 225
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 229
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 232
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 227
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 229
+ 240 240 240 240 238 240 236 240 235 240 234 240 233 240 235 235
+ 209 175 77 152 230 235 178 206 154 141 220 98 240 240 189 149
+ 155 153 118 51 137 232 95 121 108 85 201 76 240 240 86 155
+ 72 163 240 155 125 237 107 128 101 109 179 58 219 219 98 127
+ 85 186 217 45 150 151 17 148 110 106 184 50 73 51 83 147
+ 216 53 50 120 240 30 92 200 170 109 184 47 211 186 84 156
+ 240 226 180 240 240 225 236 238 151 115 205 66 228 238 116 150
+ 240 240 240 240 240 240 240 240 180 225 212 182 240 240 156 225
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 228
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 232
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 235
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 232
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 240 240 240 240 240 240 240 240 227
+ 239 240 240 240 240 240 240 240 240 240 240 240 240 240 240 229
+ 233 240 240 240 238 240 236 240 235 240 234 240 233 240 235 234
+
+ 149 149 121 149 150 150 225 229 231 236 234 236 240 227 229 234
+ 186 71 84 63 62 107 149 240 240 240 240 240 240 240 240 235
+ 240 240 220 47 181 238 240 240 240 240 240 240 240 240 240 240
+ 240 240 222 78 213 231 240 240 240 240 240 240 240 240 240 233
+ 98 76 58 53 62 75 186 240 240 240 240 240 240 240 240 240
+ 219 210 180 184 187 208 216 240 240 240 240 240 240 240 240 234
+ 135 98 121 113 113 115 225 240 240 240 240 240 240 240 240 240
+ 152 109 92 101 169 147 174 240 240 240 240 240 240 240 240 235
+ 207 122 128 142 197 238 240 240 240 240 240 240 240 240 240 240
+ 191 108 109 5 72 228 240 240 240 240 240 240 240 240 240 237
+ 236 240 237 150 29 223 240 240 240 240 240 240 240 240 240 240
+ 227 129 124 150 237 226 237 240 240 240 240 240 240 240 240 238
+ 152 51 155 45 120 237 238 240 240 240 240 240 240 240 240 240
+ 77 119 232 217 50 180 240 240 240 240 240 240 240 240 240 240
+ 175 161 161 186 53 226 240 240 240 240 240 240 240 240 240 240
+ 209 155 64 83 207 240 240 240 240 240 240 240 240 239 228 232
+ 140 148 117 144 150 150 225 229 232 236 234 236 240 227 229 235
+ 186 71 89 77 74 117 156 240 240 240 240 240 240 240 240 235
+ 240 240 219 51 187 240 240 240 240 240 240 240 240 240 240 240
+ 240 240 219 74 213 231 240 240 240 240 240 240 240 240 240 233
+ 98 76 65 61 51 72 186 240 240 240 240 240 240 240 240 240
+ 220 210 184 184 184 206 216 240 240 240 240 240 240 240 240 234
+ 150 109 121 106 103 115 225 240 240 240 240 240 240 240 240 240
+ 156 109 92 101 168 162 186 240 240 240 240 240 240 240 240 235
+ 207 121 128 142 197 240 240 240 240 240 240 240 240 240 240 240
+ 192 99 100 5 78 232 240 240 240 240 240 240 240 240 240 236
+ 236 240 236 150 29 223 240 240 240 240 240 240 240 240 240 240
+ 230 137 125 152 237 237 240 240 240 240 240 240 240 240 240 238
+ 152 51 156 52 120 240 240 240 240 240 240 240 240 240 240 240
+ 77 120 240 217 50 180 240 240 240 240 240 240 240 240 240 240
+ 176 166 170 186 53 226 240 240 240 240 240 240 240 240 240 240
+ 212 164 73 85 216 240 240 240 240 240 240 240 240 240 240 240
+ 149 155 127 147 156 150 225 228 232 235 232 234 240 227 229 234
+ 189 86 98 83 84 116 156 240 240 240 240 240 240 240 240 235
+ 240 240 219 51 186 238 240 240 240 240 240 240 240 240 240 240
+ 240 240 219 73 211 228 240 240 240 240 240 240 240 240 240 233
+ 98 76 58 50 47 66 182 240 240 240 240 240 240 240 240 240
+ 220 201 179 184 184 205 212 240 240 240 240 240 240 240 240 234
+ 141 85 109 106 109 115 225 240 240 240 240 240 240 240 240 240
+ 154 108 101 110 170 151 180 240 240 240 240 240 240 240 240 235
+ 206 121 128 148 200 238 240 240 240 240 240 240 240 240 240 240
+ 178 95 107 17 92 236 240 240 240 240 240 240 240 240 240 236
+ 235 232 237 151 30 225 240 240 240 240 240 240 240 240 240 240
+ 230 137 125 150 240 240 240 240 240 240 240 240 240 240 240 238
+ 152 51 155 45 120 240 240 240 240 240 240 240 240 240 240 240
+ 77 118 240 217 50 180 240 240 240 240 240 240 240 240 240 240
+ 175 153 163 186 53 226 240 240 240 240 240 240 240 240 240 240
+ 209 155 72 85 216 240 240 240 240 240 240 240 240 240 239 233
+
--- /dev/null
+ 214 225 240 225 214 240 216 204 214 227 181 192 198 192 181 192
+ 240 240 240 240 240 240 225 232 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 75 128 220 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 106 53 240 240 240 240 240 240 240 237
+ 240 240 240 240 240 238 118 31 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 74 49 207 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 53 54 177 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 64 31 130 240 240 240 240 240 240 219
+ 240 240 240 240 240 180 37 57 78 228 240 240 240 240 240 240
+ 240 240 240 240 240 118 62 157 36 185 240 240 240 240 240 231
+ 240 240 240 240 240 82 65 225 67 80 230 240 240 240 240 217
+ 240 240 240 225 53 76 225 240 156 62 158 240 240 240 240 226
+ 240 240 199 61 9 111 235 240 240 104 58 174 228 240 240 240
+ 240 142 64 26 92 227 240 240 240 229 93 64 170 226 238 216
+ 90 26 12 156 240 240 240 240 240 240 204 95 30 117 192 200
+ 156 16 195 233 235 240 236 240 238 239 240 186 93 53 120 237
+ 214 226 240 225 212 240 216 204 212 226 181 192 198 192 185 194
+ 240 240 240 240 240 240 227 232 240 240 240 240 240 240 240 238
+ 240 240 240 240 240 240 95 138 225 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 108 59 240 240 240 240 240 240 240 237
+ 240 240 240 240 240 238 118 31 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 83 47 207 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 56 49 177 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 73 41 130 240 240 240 240 240 240 222
+ 240 240 240 240 240 185 46 49 86 230 240 240 240 240 240 240
+ 240 240 240 240 240 118 58 165 45 192 240 240 240 240 240 234
+ 240 240 240 240 240 91 63 222 74 82 240 240 240 240 240 222
+ 240 240 240 226 66 86 225 240 158 63 162 240 240 240 240 228
+ 240 240 202 76 11 103 235 240 234 91 49 174 228 240 240 240
+ 240 142 68 16 91 226 240 240 240 228 96 74 178 233 239 222
+ 90 26 4 150 240 240 240 240 240 240 213 109 46 133 204 213
+ 156 14 195 234 236 240 237 240 239 240 240 192 106 57 125 238
+ 214 226 240 225 212 240 216 204 214 227 181 192 198 192 184 192
+ 240 240 240 240 240 240 226 232 240 240 240 240 240 240 240 236
+ 240 240 240 240 240 240 85 134 220 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 107 58 240 240 240 240 240 240 240 237
+ 240 240 240 240 240 238 118 32 240 240 240 240 240 240 240 234
+ 240 240 240 240 240 240 87 60 210 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 58 58 178 240 240 240 240 240 240 240
+ 240 240 240 240 240 240 73 31 130 240 240 240 240 240 240 219
+ 240 240 240 240 240 185 46 59 86 228 240 240 240 240 240 240
+ 240 240 240 240 240 118 62 168 41 186 240 240 240 240 240 231
+ 240 240 240 240 240 90 65 225 60 92 235 240 240 240 240 219
+ 240 240 240 225 53 82 225 240 146 63 163 240 240 240 240 228
+ 240 240 198 61 5 103 235 240 234 102 58 175 232 240 240 240
+ 240 134 54 13 91 226 240 240 240 229 96 68 188 238 239 222
+ 90 15 3 150 240 240 240 240 240 240 213 105 48 134 204 213
+ 156 14 195 233 236 240 237 240 239 239 240 192 106 57 125 238
+
+ 192 236 240 237 234 240 240 219 240 231 217 226 240 216 200 237
+ 181 240 240 240 240 240 240 240 240 240 240 240 240 238 192 120
+ 192 240 240 240 240 240 240 240 240 240 240 240 240 226 117 53
+ 198 240 240 240 240 240 240 240 240 240 240 240 228 170 30 93
+ 192 240 240 240 240 240 240 240 240 240 240 240 174 64 95 186
+ 181 240 240 240 240 240 240 240 240 240 230 158 58 93 204 240
+ 227 240 240 240 240 240 240 240 228 185 80 62 104 229 240 239
+ 214 240 220 240 240 207 177 130 78 36 67 156 240 240 240 238
+ 204 232 128 53 31 49 54 31 57 157 225 240 240 240 240 240
+ 216 225 75 106 118 74 53 64 37 62 65 225 235 240 240 236
+ 240 240 240 240 238 240 240 240 180 118 82 76 111 227 240 240
+ 214 240 240 240 240 240 240 240 240 240 240 53 9 92 240 235
+ 225 240 240 240 240 240 240 240 240 240 240 225 61 26 156 233
+ 240 240 240 240 240 240 240 240 240 240 240 240 199 64 12 195
+ 225 240 240 240 240 240 240 240 240 240 240 240 240 142 26 16
+ 214 240 240 240 240 240 240 240 240 240 240 240 240 240 90 156
+ 194 238 240 237 234 240 240 222 240 234 222 228 240 222 213 238
+ 185 240 240 240 240 240 240 240 240 240 240 240 240 239 204 125
+ 192 240 240 240 240 240 240 240 240 240 240 240 240 233 133 57
+ 198 240 240 240 240 240 240 240 240 240 240 240 228 178 46 106
+ 192 240 240 240 240 240 240 240 240 240 240 240 174 74 109 192
+ 181 240 240 240 240 240 240 240 240 240 240 162 49 96 213 240
+ 226 240 240 240 240 240 240 240 230 192 82 63 91 228 240 240
+ 212 240 225 240 240 207 177 130 86 45 74 158 234 240 240 239
+ 204 232 138 59 31 47 49 41 49 165 222 240 240 240 240 240
+ 216 227 95 108 118 83 56 73 46 58 63 225 235 240 240 237
+ 240 240 240 240 238 240 240 240 185 118 91 86 103 226 240 240
+ 212 240 240 240 240 240 240 240 240 240 240 66 11 91 240 236
+ 225 240 240 240 240 240 240 240 240 240 240 226 76 16 150 234
+ 240 240 240 240 240 240 240 240 240 240 240 240 202 68 4 195
+ 226 240 240 240 240 240 240 240 240 240 240 240 240 142 26 14
+ 214 240 240 240 240 240 240 240 240 240 240 240 240 240 90 156
+ 192 236 240 237 234 240 240 219 240 231 219 228 240 222 213 238
+ 184 240 240 240 240 240 240 240 240 240 240 240 240 239 204 125
+ 192 240 240 240 240 240 240 240 240 240 240 240 240 238 134 57
+ 198 240 240 240 240 240 240 240 240 240 240 240 232 188 48 106
+ 192 240 240 240 240 240 240 240 240 240 240 240 175 68 105 192
+ 181 240 240 240 240 240 240 240 240 240 235 163 58 96 213 240
+ 227 240 240 240 240 240 240 240 228 186 92 63 102 229 240 239
+ 214 240 220 240 240 210 178 130 86 41 60 146 234 240 240 239
+ 204 232 134 58 32 60 58 31 59 168 225 240 240 240 240 240
+ 216 226 85 107 118 87 58 73 46 62 65 225 235 240 240 237
+ 240 240 240 240 238 240 240 240 185 118 90 82 103 226 240 240
+ 212 240 240 240 240 240 240 240 240 240 240 53 5 91 240 236
+ 225 240 240 240 240 240 240 240 240 240 240 225 61 13 150 233
+ 240 240 240 240 240 240 240 240 240 240 240 240 198 54 3 195
+ 226 240 240 240 240 240 240 240 240 240 240 240 240 134 15 14
+ 214 240 240 240 240 240 240 240 240 240 240 240 240 240 90 156
+
+ 237 120 53 93 186 240 239 238 240 236 240 235 233 195 16 156
+ 200 192 117 30 95 204 240 240 240 240 240 240 156 12 26 90
+ 216 238 226 170 64 93 229 240 240 240 227 92 26 64 142 240
+ 240 240 240 228 174 58 104 240 240 235 111 9 61 199 240 240
+ 226 240 240 240 240 158 62 156 240 225 76 53 225 240 240 240
+ 217 240 240 240 240 230 80 67 225 65 82 240 240 240 240 240
+ 231 240 240 240 240 240 185 36 157 62 118 240 240 240 240 240
+ 240 240 240 240 240 240 228 78 57 37 180 240 240 240 240 240
+ 219 240 240 240 240 240 240 130 31 64 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 177 54 53 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 207 49 74 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 31 118 238 240 240 240 240 240
+ 237 240 240 240 240 240 240 240 53 106 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 220 128 75 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 232 225 240 240 240 240 240 240
+ 192 181 192 198 192 181 227 214 204 216 240 214 225 240 225 214
+ 238 125 57 106 192 240 240 239 240 237 240 236 234 195 14 156
+ 213 204 133 46 109 213 240 240 240 240 240 240 150 4 26 90
+ 222 239 233 178 74 96 228 240 240 240 226 91 16 68 142 240
+ 240 240 240 228 174 49 91 234 240 235 103 11 76 202 240 240
+ 228 240 240 240 240 162 63 158 240 225 86 66 226 240 240 240
+ 222 240 240 240 240 240 82 74 222 63 91 240 240 240 240 240
+ 234 240 240 240 240 240 192 45 165 58 118 240 240 240 240 240
+ 240 240 240 240 240 240 230 86 49 46 185 240 240 240 240 240
+ 222 240 240 240 240 240 240 130 41 73 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 177 49 56 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 207 47 83 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 31 118 238 240 240 240 240 240
+ 237 240 240 240 240 240 240 240 59 108 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 225 138 95 240 240 240 240 240 240
+ 238 240 240 240 240 240 240 240 232 227 240 240 240 240 240 240
+ 194 185 192 198 192 181 226 212 204 216 240 212 225 240 226 214
+ 238 125 57 106 192 240 239 239 240 237 240 236 233 195 14 156
+ 213 204 134 48 105 213 240 240 240 240 240 240 150 3 15 90
+ 222 239 238 188 68 96 229 240 240 240 226 91 13 54 134 240
+ 240 240 240 232 175 58 102 234 240 235 103 5 61 198 240 240
+ 228 240 240 240 240 163 63 146 240 225 82 53 225 240 240 240
+ 219 240 240 240 240 235 92 60 225 65 90 240 240 240 240 240
+ 231 240 240 240 240 240 186 41 168 62 118 240 240 240 240 240
+ 240 240 240 240 240 240 228 86 59 46 185 240 240 240 240 240
+ 219 240 240 240 240 240 240 130 31 73 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 178 58 58 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 210 60 87 240 240 240 240 240 240
+ 234 240 240 240 240 240 240 240 32 118 238 240 240 240 240 240
+ 237 240 240 240 240 240 240 240 58 107 240 240 240 240 240 240
+ 240 240 240 240 240 240 240 220 134 85 240 240 240 240 240 240
+ 236 240 240 240 240 240 240 240 232 226 240 240 240 240 240 240
+ 192 184 192 198 192 181 227 214 204 216 240 212 225 240 226 214
+
+ 156 90 240 240 240 240 240 240 240 240 240 240 240 240 240 214
+ 16 26 142 240 240 240 240 240 240 240 240 240 240 240 240 225
+ 195 12 64 199 240 240 240 240 240 240 240 240 240 240 240 240
+ 233 156 26 61 225 240 240 240 240 240 240 240 240 240 240 225
+ 235 240 92 9 53 240 240 240 240 240 240 240 240 240 240 214
+ 240 240 227 111 76 82 118 180 240 240 240 238 240 240 240 240
+ 236 240 240 235 225 65 62 37 64 53 74 118 106 75 225 216
+ 240 240 240 240 240 225 157 57 31 54 49 31 53 128 232 204
+ 238 240 240 240 156 67 36 78 130 177 207 240 240 220 240 214
+ 239 240 229 104 62 80 185 228 240 240 240 240 240 240 240 227
+ 240 204 93 58 158 230 240 240 240 240 240 240 240 240 240 181
+ 186 95 64 174 240 240 240 240 240 240 240 240 240 240 240 192
+ 93 30 170 228 240 240 240 240 240 240 240 240 240 240 240 198
+ 53 117 226 240 240 240 240 240 240 240 240 240 240 240 240 192
+ 120 192 238 240 240 240 240 240 240 240 240 240 240 240 240 181
+ 237 200 216 240 226 217 231 240 219 240 240 234 237 240 236 192
+ 156 90 240 240 240 240 240 240 240 240 240 240 240 240 240 214
+ 14 26 142 240 240 240 240 240 240 240 240 240 240 240 240 226
+ 195 4 68 202 240 240 240 240 240 240 240 240 240 240 240 240
+ 234 150 16 76 226 240 240 240 240 240 240 240 240 240 240 225
+ 236 240 91 11 66 240 240 240 240 240 240 240 240 240 240 212
+ 240 240 226 103 86 91 118 185 240 240 240 238 240 240 240 240
+ 237 240 240 235 225 63 58 46 73 56 83 118 108 95 227 216
+ 240 240 240 240 240 222 165 49 41 49 47 31 59 138 232 204
+ 239 240 240 234 158 74 45 86 130 177 207 240 240 225 240 212
+ 240 240 228 91 63 82 192 230 240 240 240 240 240 240 240 226
+ 240 213 96 49 162 240 240 240 240 240 240 240 240 240 240 181
+ 192 109 74 174 240 240 240 240 240 240 240 240 240 240 240 192
+ 106 46 178 228 240 240 240 240 240 240 240 240 240 240 240 198
+ 57 133 233 240 240 240 240 240 240 240 240 240 240 240 240 192
+ 125 204 239 240 240 240 240 240 240 240 240 240 240 240 240 185
+ 238 213 222 240 228 222 234 240 222 240 240 234 237 240 238 194
+ 156 90 240 240 240 240 240 240 240 240 240 240 240 240 240 214
+ 14 15 134 240 240 240 240 240 240 240 240 240 240 240 240 226
+ 195 3 54 198 240 240 240 240 240 240 240 240 240 240 240 240
+ 233 150 13 61 225 240 240 240 240 240 240 240 240 240 240 225
+ 236 240 91 5 53 240 240 240 240 240 240 240 240 240 240 212
+ 240 240 226 103 82 90 118 185 240 240 240 238 240 240 240 240
+ 237 240 240 235 225 65 62 46 73 58 87 118 107 85 226 216
+ 240 240 240 240 240 225 168 59 31 58 60 32 58 134 232 204
+ 239 240 240 234 146 60 41 86 130 178 210 240 240 220 240 214
+ 239 240 229 102 63 92 186 228 240 240 240 240 240 240 240 227
+ 240 213 96 58 163 235 240 240 240 240 240 240 240 240 240 181
+ 192 105 68 175 240 240 240 240 240 240 240 240 240 240 240 192
+ 106 48 188 232 240 240 240 240 240 240 240 240 240 240 240 198
+ 57 134 238 240 240 240 240 240 240 240 240 240 240 240 240 192
+ 125 204 239 240 240 240 240 240 240 240 240 240 240 240 240 184
+ 238 213 222 240 228 219 231 240 219 240 240 234 237 240 236 192
+
--- /dev/null
+ARToolkit Java class library NyARToolkit.\r
+Copyright (C)2008-2009 Ryo Iizuka\r
+\r
+This program is free software: you can redistribute it and/or modify\r
+it under the terms of the GNU General Public License as published by\r
+the Free Software Foundation, either version 3 of the License, or\r
+(at your option) any later version.\r
+\r
+This program is distributed in the hope that it will be useful,\r
+but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+GNU General Public License for more details.\r
+\r
+You should have received a copy of the GNU General Public License\r
+along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+\r
+\r
+ \r
+\r
+Java版 ARToolkit クラスライブラリ NyARToolkit\r
+Copyright (C)2008-2009 Ryo Iizuka\r
+\r
+このプログラムはフリーソフトウェアです。あなたはこれを、フリーソフトウェア\r
+財団によって発行されたGNU 一般公衆利用許諾書(バージョン3か、それ以降のバー\r
+ジョンのうちどれか)が定める条件の下で再頒布または改変 することができます。\r
+\r
+このプログラムは有用であることを願って頒布されますが、*全くの無保証 *です。\r
+商業可能性の保証や特定目的への適合性は、言外に示されたものも 含め、全く存\r
+在しません。詳しくはGNU 一般公衆利用許諾書をご覧ください。\r
+\r
+あなたはこのプログラムと共に、GNU 一般公衆利用許諾書のコピーを一部受け取って\r
+いるはずです。もし受け取っていなければ、<http://www.gnu.org/licenses/> を\r
+ご覧ください。
\ No newline at end of file
--- /dev/null
+準備中です。ゴメンネ\r
+\r
+Not ready.
\ No newline at end of file
--- /dev/null
+ARToolKit Java class library NyARToolkit.\r
+Copyright (C)2008 R.Iizuka\r
+\r
+version 2.4.1\r
+\r
+http://nyatla.jp/nyartoolkit/\r
+airmail(at)ebony.plala.or.jp\r
+wm(at)nyatla.jp\r
+--------------------------------------------------\r
+\r
+\r
+\r
+\r
+・NyARToolkit/2.4\r
+\r
+NyARToolkitは、Pure Javaで実装したARToolKitクラスライブラリです。\r
+\r
+ARToolKit 2.72.1をベースに構築されています。\r
+\r
+J2SEでのみ動作を確認しました。\r
+J2MEやMIDP2.0にはそのうち対応します。\r
+\r
+\r
+ARToolkitは加藤博一先生とHuman Interface Technology Labにより\r
+開発されたAugmented Reality (AR) ライブラリです。\r
+詳しくはこちらをご覧下さい。\r
+http://www.hitl.washington.edu/artoolkit/\r
+\r
+\r
+・NyARToolkitの特徴\r
+\r
+ -ARToolKitと同等な処理シーケンスを、クラスベースで再構築しています。\r
+\r
+ -ARToolKitと比較して、処理構造が最適化されています。\r
+\r
+ -ARToolKit互換モードと、NyARToolkit最適化モードを搭載しています。(Version/2.4.0より)\r
+ \r
+ --NyARToolkit最適化モード\r
+ いくつかのアルゴリズムをARToolKitのものと差換え、高速化・精度の向上を図ります。\r
+ ARToolKit比で、約2倍高速です。(JIT有効時)複数マーカー取り扱い時は、\r
+ 更に高速になります。ただし、計算結果はARToolKitのそれと若干ズレがでます。\r
+\r
+ --ARToolKit互換モード\r
+ ARToolKitのアルゴリズムを最適化し、高速化を図ります。\r
+ ARToolKit比で、約1倍高速です。(JIT有効時)\r
+\r
+ -取り扱える画像サイズに制限がありません。\r
+ -取り扱えるマーカー個数の最大値が可変です。\r
+ -Idマーカシステム(NyId)が利用できます。(Version/2.3.0より)\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+・構成\r
+\r
++-----------------------------------------------+\r
+| Application |\r
++-------+---------+--------+--------+-----------+\r
+|NyARJMF|CaptureQT| NyARJoglNyARJ3d | |\r
++-------+---------+--------+--------+ |\r
+| JMF |QuickTime| JOGL | Java3D |NyARToolkit|\r
++-------+---------+--------+--------+ |\r
+| Camera | 3D | |\r
+------------------------------------+-----------+\r
+\r
+\r
+映像キャプチャにはJMF、又はQuickTimeを使用することが出来ます。\r
+\r
+3D描画にはJOGL又はJava3Dを使用することが出来ます。\r
+\r
+NyARJMF/CaptureQT/NyARJog/NyARJ3dは、下位のキャプチャモジュール\r
+や3Dライブラリを使いやすくするためのラッパークラス群です。\r
+\r
+各モジュールとNyARToolkitは分離可能であり、個々を単独で使用する\r
+ことも可能です。\r
+\r
+\r
+\r
+\r
+・サンプルなど\r
+\r
+1.動作させる前に、JMFとJOGLかJava3Dをインストールしてください。\r
+ QuickTimeを使う場合には、QuickTime for Javaも必要です。\r
+\r
+\r
+動作確認したバージョンと入手先はこちらです。\r
+\r
+JMF JavaTM Media Framework 2.1.1e\r
+http://java.sun.com/products/java-media/jmf/index.jsp\r
+\r
+jogl-1.1.1-pre-20080328-xxxx-i586.zip\r
+https://jogl.dev.java.net/\r
+\r
+java3d-1_5_1-xxxx-i586.exe\r
+https://java3d.dev.java.net/binary-builds.html\r
+\r
+QuickTime 7.5\r
+http://www.apple.com/quicktime/qtjava/\r
+\r
+\r
+\r
+2.eclipseで空のワークスペースを作成し、sample,src,src.utils\r
+ ディレクトリをインポートしてください。\r
+\r
+srcディレクトリには、NyARToolkit本体(計算クラス群)があります。\r
+src.utilsディレクトリには、カメラキャプチャクラスや、3Dライブラリ用のラッパークラス群があります。\r
+sampleディレクトリには、NyARToolkitを使用したサンプルプログラムがあります。\r
+\r
+\r
+・プロジェクトの説明\r
+\r
+ライブラリ\r
+\r
+NyARToolkit\r
+ NyARToolkitライブラリの本体です。依存する外部モジュールはありません。\r
+\r
+NyARToolkit.utils.jmf\r
+ JMFからの画像をNyARToolkitに取り込むクラス群があります。\r
+ 外部ライブラリは、JMFに依存します。\r
+\r
+NyARToolkit.utils.qt\r
+ QuickTimeからの画像をNyARToolkitに取り込むクラス群があります。\r
+ 外部ライブラリは、JMF、QuickTime for Javaに依存します。\r
+\r
+NyARToolkit.utils.jogl\r
+ OpenGLとNyARToolkitのインタフェイスクラス群があります。\r
+ 外部ライブラリは、JMF,JOGLに依存します。\r
+\r
+NyARToolkit.utils.java3d\r
+ Java3DとNyARToolkitのインタフェイスクラス群があります。\r
+ 外部ライブラリは、JMF,Java3Dに依存します。\r
+\r
+\r
+サンプル\r
+\r
+NyARToolkit.sample.jogl\r
+ JOGL/JMFを使ったサンプルプログラムがあります。\r
+\r
+ -jp.nyatla.nyartoolkit.jogl.sample.JavaSimpleLite\r
+ 単一のARToolKit用マーカーを認識するARToolkitのsimpleLite相当のサンプルです。\r
+ -jp.nyatla.nyartoolkit.jogl.sample.JavaSimpleLite2\r
+ 複数のARToolKit用マーカーを認識するサンプルです。1~100個程度のマーカーを\r
+ 同時に認識します。\r
+ -jp.nyatla.nyartoolkit.jogl.sample.SingleNyIdMarker\r
+ 単一のNyIdマーカを認識するためのサンプルです。アプリケーションフレームワーク\r
+ SingleNyIdMarkerProcesserのリファレンス実装です。\r
+\r
+\r
+NyARToolkit.sample.java3d\r
+ JOGL/JMFを使ったサンプルプログラムです。\r
+ \r
+ -jp.nyatla.nyartoolkit.java3d.sample\r
+ simpleLiteをJava3Dで動かすサンプルがあります。\r
+\r
+NyARToolkit.sample.jmf\r
+ JMFを使ったサンプルプログラムです。\r
+\r
+ -jp.nyatla..nyartoolkit.jmf.sample\r
+ JMFでキャプチャした画像をNyARToolkitで処理するサンプルプログラムです。\r
+ \r
+\r
+NyARToolkit.sample.qt\r
+ Quicktime for Javaを使ったサンプルプログラムです。\r
+\r
+ -jp.nyatla.nyartoolkit.qt.sample\r
+ QuickTimeでキャプチャした画像をNyARToolkitで処理するサンプルプログラムです。\r
+ \r
+\r
+\r
+\r
+\r
+・足りない機能等\r
+\r
+カメラキャリブレーション、マーカーのセーブ機能等が相変わらずありません。\r
+今後実装していきます。\r
+\r
+\r
+\r
+\r
+・ライセンス\r
+\r
+NyARToolkitは、商用ライセンスとGPLv3以降のデュアルライセンスを採用しています。\r
+(Version/2.4.0より、GPLv3ライセンスになりました。)\r
+\r
+ -GPL\r
+ GPLについては、LICENCE.txtをお読みください。\r
+\r
+ -商用ライセンス\r
+ 商用ライセンスについては、ARToolWorks社に管理を委託しております。\r
+ http://www.artoolworks.com/Home.html\r
+\r
+ 日本国内での販売については、下記にお問い合わせ下さい。\r
+ http://www.msoft.co.jp/pressrelease/press090928-1.html\r
+\r
+\r
+\r
+・謝辞\r
+\r
+arc@dmzさん\r
+http://digitalmuseum.jp/\r
+\r
+QuickTimeキャプチャモジュールを提供をして頂きました。有難うございます。
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry path="" kind="src"/>\r
+ <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>\r
+ <classpathentry sourcepath="/jmfapp" path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/Java/Java3D/1.5.1/lib/ext/j3dcore.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/Java/Java3D/1.5.1/lib/ext/j3dutils.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/Java/Java3D/1.5.1/lib/ext/vecmath.jar" kind="lib"/>\r
+ <classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="/NyARToolkit.utils.jmf" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="/NyARToolkit.utils.java3d" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="" kind="output"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolkit.sample.java3d</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit Java3d sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.java3d.sample;\r
+\r
+import java.awt.BorderLayout;\r
+import javax.media.j3d.*;\r
+\r
+import com.sun.j3d.utils.universe.*;\r
+import java.awt.*;\r
+import javax.swing.JFrame;\r
+import javax.vecmath.*;\r
+\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.java3d.utils.*;\r
+\r
+import com.sun.j3d.utils.geometry.ColorCube;\r
+\r
+/**\r
+ * Java3Dサンプルプログラム\r
+ * 単一マーカー追跡用のBehaviorを使って、背景と1個のマーカーに連動した\r
+ * TransformGroupを動かします。\r
+ *\r
+ */\r
+public class NyARJava3D extends JFrame implements NyARSingleMarkerBehaviorListener\r
+{\r
+ private static final long serialVersionUID = -8472866262481865377L;\r
+\r
+ private final String CARCODE_FILE = "../../Data/patt.hiro";\r
+\r
+ private final String PARAM_FILE = "../../Data/camera_para.dat";\r
+\r
+ //NyARToolkit関係\r
+ private NyARSingleMarkerBehaviorHolder nya_behavior;\r
+\r
+ private J3dNyARParam ar_param;\r
+\r
+ //universe関係\r
+ private Canvas3D canvas;\r
+\r
+ private Locale locale;\r
+\r
+ private VirtualUniverse universe;\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ try {\r
+ NyARJava3D frame = new NyARJava3D();\r
+\r
+ frame.setVisible(true);\r
+ Insets ins = frame.getInsets();\r
+ frame.setSize(320 + ins.left + ins.right, 240 + ins.top + ins.bottom);\r
+ frame.startCapture();\r
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void onUpdate(boolean i_is_marker_exist, Transform3D i_transform3d)\r
+ {\r
+ /*\r
+ * TODO:Please write your behavior operation code here.\r
+ * マーカーの姿勢を元に他の3Dオブジェクトを操作するときは、ここに処理を書きます。*/\r
+\r
+ }\r
+\r
+ public void startCapture() throws Exception\r
+ {\r
+ nya_behavior.start();\r
+ }\r
+\r
+ public NyARJava3D() throws Exception\r
+ {\r
+ super("Java3D Example NyARToolkit");\r
+\r
+ //NyARToolkitの準備\r
+ NyARCode ar_code = new NyARCode(16, 16);\r
+ ar_code.loadARPattFromFile(CARCODE_FILE);\r
+ ar_param = new J3dNyARParam();\r
+ ar_param.loadARParamFromFile(PARAM_FILE);\r
+ ar_param.changeScreenSize(320, 240);\r
+\r
+ //localeの作成とlocateとviewの設定\r
+ universe = new VirtualUniverse();\r
+ locale = new Locale(universe);\r
+ canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());\r
+ View view = new View();\r
+ ViewPlatform viewPlatform = new ViewPlatform();\r
+ view.attachViewPlatform(viewPlatform);\r
+ view.addCanvas3D(canvas);\r
+ view.setPhysicalBody(new PhysicalBody());\r
+ view.setPhysicalEnvironment(new PhysicalEnvironment());\r
+\r
+ //視界の設定(カメラ設定から取得)\r
+ Transform3D camera_3d = ar_param.getCameraTransform();\r
+ view.setCompatibilityModeEnable(true);\r
+ view.setProjectionPolicy(View.PERSPECTIVE_PROJECTION);\r
+ view.setLeftProjection(camera_3d);\r
+\r
+ //視点設定(0,0,0から、Y軸を180度回転してZ+方向を向くようにする。)\r
+ TransformGroup viewGroup = new TransformGroup();\r
+ Transform3D viewTransform = new Transform3D();\r
+ viewTransform.rotY(Math.PI);\r
+ viewTransform.setTranslation(new Vector3d(0.0, 0.0, 0.0));\r
+ viewGroup.setTransform(viewTransform);\r
+ viewGroup.addChild(viewPlatform);\r
+ BranchGroup viewRoot = new BranchGroup();\r
+ viewRoot.addChild(viewGroup);\r
+ locale.addBranchGraph(viewRoot);\r
+\r
+ //バックグラウンドの作成\r
+ Background background = new Background();\r
+ BoundingSphere bounds = new BoundingSphere();\r
+ bounds.setRadius(10.0);\r
+ background.setApplicationBounds(bounds);\r
+ background.setImageScaleMode(Background.SCALE_FIT_ALL);\r
+ background.setCapability(Background.ALLOW_IMAGE_WRITE);\r
+ BranchGroup root = new BranchGroup();\r
+ root.addChild(background);\r
+\r
+ //TransformGroupで囲ったシーングラフの作成\r
+ TransformGroup transform = new TransformGroup();\r
+ transform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);\r
+ transform.addChild(createSceneGraph());\r
+ root.addChild(transform);\r
+\r
+ //NyARToolkitのBehaviorを作る。(マーカーサイズはメートルで指定すること)\r
+ nya_behavior = new NyARSingleMarkerBehaviorHolder(ar_param, 30f, ar_code, 0.08);\r
+ //Behaviorに連動するグループをセット\r
+ nya_behavior.setTransformGroup(transform);\r
+ nya_behavior.setBackGround(background);\r
+\r
+ //出来たbehaviorをセット\r
+ root.addChild(nya_behavior.getBehavior());\r
+ nya_behavior.setUpdateListener(this);\r
+\r
+ //表示ブランチをLocateにセット\r
+ locale.addBranchGraph(root);\r
+\r
+ //ウインドウの設定\r
+ setLayout(new BorderLayout());\r
+ add(canvas, BorderLayout.CENTER);\r
+ }\r
+\r
+ /**\r
+ * シーングラフを作って、そのノードを返す。\r
+ * このノードは40mmの色つき立方体を表示するシーン。z軸を基準に20mm上に浮かせてる。\r
+ * @return\r
+ */\r
+ private Node createSceneGraph()\r
+ {\r
+ TransformGroup tg = new TransformGroup();\r
+ Transform3D mt = new Transform3D();\r
+ mt.setTranslation(new Vector3d(0.00, 0.0, 20 * 0.001));\r
+ // 大きさ 40mmの色付き立方体を、Z軸上で20mm動かして配置)\r
+ tg.setTransform(mt);\r
+ tg.addChild(new ColorCube(20 * 0.001));\r
+ return tg;\r
+ }\r
+}\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry path="" kind="src"/>\r
+ <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>\r
+ <classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>\r
+ <classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="/NyARToolkit.utils.jmf" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="" kind="output"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolkit.sample.jmf</name>\r
+ <comment></comment>\r
+ <projects>\r
+ <project>NyARToolKit</project>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+/*
+ * PROJECT: NyARToolkit JMF sample program.
+ * --------------------------------------------------------------------------------
+ * The MIT License
+ * Copyright (c) 2008 nyatla
+ * airmail(at)ebony.plala.or.jp
+ * http://nyatla.jp/nyartoolkit/
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package jp.nyatla.nyartoolkit.jmf.sample;
+
+import javax.media.*;
+
+import javax.media.util.BufferToImage;
+import javax.media.format.*;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
+
+import java.awt.*;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.core.param.NyARParam;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.detector.NyARSingleDetectMarker;
+
+/**
+ * VFM+ARToolkitテストプログラム
+ * カメラから取り込んだデータからマーカーを検出して、一致度と変換行列を表示します。
+ */
+public class NyarToolkitLinkTest extends Frame implements JmfCaptureListener
+{
+ private static final long serialVersionUID = 6471434231970804953L;
+
+ private final String CARCODE_FILE = "../../Data/patt.hiro";
+
+ private final String PARAM_FILE = "../../Data/camera_para.dat";
+
+ private JmfCaptureDevice _capture;
+
+ private NyARSingleDetectMarker _nya;
+
+ private JmfNyARRaster_RGB _raster;
+
+ private NyARTransMatResult _trans_mat_result = new NyARTransMatResult();
+
+ public NyarToolkitLinkTest() throws NyARException
+ {
+ setTitle("JmfCaptureTest");
+ setBounds(0, 0, 320 + 64, 240 + 64);
+ //キャプチャの準備
+ JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();
+ this._capture=devlist.getDevice(0);
+ //JmfNyARRaster_RGBはYUVよりもRGBで高速に動作します。
+ if(!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_RGB,320, 240,15f)){
+ if(!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_YUV,320, 240,15f)){
+ throw new NyARException("キャプチャフォーマットが見つかりません");
+ }
+ }
+ this._capture.setOnCapture(this);
+ this.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e)
+ {
+ System.exit(0);
+ }
+ });
+ //NyARToolkitの準備
+ NyARParam ar_param = new NyARParam();
+ NyARCode ar_code = new NyARCode(16, 16);
+ ar_param.loadARParamFromFile(PARAM_FILE);
+ ar_param.changeScreenSize(320, 240);
+ this._raster = new JmfNyARRaster_RGB(320, 240,this._capture.getCaptureFormat());
+ this._nya = new NyARSingleDetectMarker(ar_param, ar_code, 80.0,this._raster.getBufferReader().getBufferType());
+ ar_code.loadARPattFromFile(CARCODE_FILE);
+ //キャプチャイメージ用のラスタを準備
+ return;
+ }
+
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+ try {
+ //キャプチャしたバッファをラスタにセット
+ this._raster.setBuffer(i_buffer);
+
+ //キャプチャしたイメージを表示用に加工
+ BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+ Image img = b2i.createImage(i_buffer);
+
+ Graphics g = getGraphics();
+
+ //マーカー検出
+ boolean is_marker_exist = this._nya.detectMarkerLite(this._raster, 100);
+ if (is_marker_exist) {
+ //変換行列を取得
+ this._nya.getTransmationMatrix(this._trans_mat_result);
+ }
+ //情報を画面に書く
+ g.drawImage(img, 32, 32, this);
+ if (is_marker_exist) {
+ g.drawString("マーカー検出:" + this._nya.getConfidence(), 32, 50);
+ g.drawString("[m00]" +this._trans_mat_result.m00, 32, 50 + 16*1);
+ g.drawString("[m01]" +this._trans_mat_result.m01, 32, 50 + 16*2);
+ g.drawString("[m02]" +this._trans_mat_result.m02, 32, 50 + 16*3);
+ g.drawString("[m03]" +this._trans_mat_result.m03, 32, 50 + 16*4);
+ g.drawString("[m10]" +this._trans_mat_result.m10, 32, 50 + 16*5);
+ g.drawString("[m11]" +this._trans_mat_result.m11, 32, 50 + 16*6);
+ g.drawString("[m12]" +this._trans_mat_result.m12, 32, 50 + 16*7);
+ g.drawString("[m13]" +this._trans_mat_result.m13, 32, 50 + 16*8);
+ g.drawString("[m20]" +this._trans_mat_result.m20, 32, 50 + 16*9);
+ g.drawString("[m21]" +this._trans_mat_result.m21, 32, 50 + 16*10);
+ g.drawString("[m22]" +this._trans_mat_result.m22, 32, 50 + 16*11);
+ g.drawString("[m23]" +this._trans_mat_result.m23, 32, 50 + 16*12);
+ } else {
+ g.drawString("マーカー未検出:", 32, 100);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void startCapture()
+ {
+ try {
+ this._capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ NyarToolkitLinkTest mainwin = new NyarToolkitLinkTest();
+ mainwin.setVisible(true);
+ mainwin.startCapture();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry path="" kind="src"/>\r
+ <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>\r
+ <classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>\r
+ <classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="/NyARToolkit.utils.jmf" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="/NyARToolkit.utils.jogl" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="C:/Program Files/Java/jre1.6.0_03/lib/gluegen-rt.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/Java/jre1.6.0_03/lib/jogl.jar" kind="lib"/>\r
+ <classpathentry path="" kind="output"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolkit.sample.jogl</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JOGL sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jogl.sample;\r
+\r
+import java.awt.event.*;\r
+import java.awt.*;\r
+import javax.media.Buffer;\r
+import javax.media.opengl.*;\r
+import com.sun.opengl.util.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+\r
+/**\r
+ * simpleLiteと同じようなテストプログラム 出来る限りARToolKitのサンプルと似せて作ってあります。 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。\r
+ * \r
+ */\r
+public class JavaSimpleLite implements GLEventListener, JmfCaptureListener\r
+{\r
+ private final static int SCREEN_X = 640;\r
+\r
+ private final static int SCREEN_Y = 480;\r
+\r
+ private Animator _animator;\r
+\r
+ private GLNyARRaster_RGB _cap_image;\r
+\r
+ private JmfCaptureDevice _capture;\r
+\r
+ private GL _gl;\r
+\r
+ private NyARGLUtil _glnya;\r
+\r
+ // NyARToolkit関係\r
+ private NyARSingleDetectMarker _nya;\r
+\r
+ private NyARParam _ar_param;\r
+\r
+ private Object _sync_object=new Object();\r
+ private double[] _camera_projection = new double[16];\r
+\r
+ /**\r
+ * 立方体を書く\r
+ * \r
+ */\r
+ void drawCube()\r
+ {\r
+ // Colour cube data.\r
+ int polyList = 0;\r
+ float fSize = 0.5f;// マーカーサイズに対して0.5倍なので、4cmの立方体\r
+ int f, i;\r
+ float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };\r
+ float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };\r
+ int cube_num_faces = 6;\r
+ short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };\r
+\r
+ if (polyList == 0) {\r
+ polyList = _gl.glGenLists(1);\r
+ _gl.glNewList(polyList, GL.GL_COMPILE);\r
+ _gl.glBegin(GL.GL_QUADS);\r
+ for (f = 0; f < cube_num_faces; f++)\r
+ for (i = 0; i < 4; i++) {\r
+ _gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);\r
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ }\r
+ _gl.glEnd();\r
+ _gl.glColor3f(0.0f, 0.0f, 0.0f);\r
+ for (f = 0; f < cube_num_faces; f++) {\r
+ _gl.glBegin(GL.GL_LINE_LOOP);\r
+ for (i = 0; i < 4; i++)\r
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ _gl.glEnd();\r
+ }\r
+ _gl.glEndList();\r
+ }\r
+\r
+ _gl.glPushMatrix(); // Save world coordinate system.\r
+ _gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.\r
+ _gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.\r
+ _gl.glDisable(GL.GL_LIGHTING); // Just use colours.\r
+ _gl.glCallList(polyList); // Draw the cube.\r
+ _gl.glPopMatrix(); // Restore world coordinate system.\r
+\r
+ }\r
+\r
+ public JavaSimpleLite(NyARParam i_param, NyARCode i_ar_code) throws NyARException\r
+ {\r
+ this._ar_param = i_param;\r
+\r
+ Frame frame = new Frame("Java simpleLite with NyARToolkit");\r
+\r
+ \r
+ // キャプチャの準備\r
+ JmfCaptureDeviceList devlist = new JmfCaptureDeviceList();\r
+ this._capture = devlist.getDevice(0);\r
+ if (!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y, 30.0f)) {\r
+ throw new NyARException();\r
+ }\r
+ this._capture.setOnCapture(this);\r
+ // GL対応のRGBラスタオブジェクト\r
+ this._cap_image = new GLNyARRaster_RGB(this._ar_param, this._capture.getCaptureFormat());\r
+ \r
+ // NyARToolkitの準備\r
+ this._nya = new NyARSingleDetectMarker(this._ar_param, i_ar_code, 80.0,this._cap_image.getBufferReader().getBufferType());\r
+ this._nya.setContinueMode(false);// ここをtrueにすると、transMatContinueモード(History計算)になります。\r
+ \r
+ // 3Dを描画するコンポーネント\r
+ GLCanvas canvas = new GLCanvas();\r
+ frame.add(canvas);\r
+ canvas.addGLEventListener(this);\r
+ frame.addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+\r
+ frame.setVisible(true);\r
+ Insets ins = frame.getInsets();\r
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
+ }\r
+\r
+ public void init(GLAutoDrawable drawable)\r
+ {\r
+ this._gl = drawable.getGL();\r
+ this._gl.glEnable(GL.GL_DEPTH_TEST);\r
+ this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+ // NyARToolkitの準備\r
+ try {\r
+ // NyARToolkit用の支援クラス\r
+ _glnya = new NyARGLUtil(_gl);\r
+ // キャプチャ開始\r
+ _capture.start();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ // カメラパラメータの計算\r
+ this._glnya.toCameraFrustumRH(this._ar_param,this._camera_projection);\r
+ this._animator = new Animator(drawable);\r
+ this._animator.start();\r
+ return;\r
+ }\r
+\r
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
+ {\r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
+ _gl.glViewport(0, 0, width, height);\r
+\r
+ // 視体積の設定\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadIdentity();\r
+ // 見る位置\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ _gl.glLoadIdentity();\r
+ }\r
+\r
+ private boolean _is_marker_exist=false;\r
+ private NyARTransMatResult __display_transmat_result = new NyARTransMatResult();\r
+\r
+ private double[] __display_wk = new double[16];\r
+\r
+ public void display(GLAutoDrawable drawable)\r
+ {\r
+ NyARTransMatResult transmat_result = __display_transmat_result;\r
+ if (!_cap_image.hasData()) {\r
+ return;\r
+ }\r
+ // 背景を書く\r
+ this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.\r
+ this._glnya.drawBackGround(this._cap_image, 1.0); \r
+ try{\r
+ synchronized(this._sync_object){\r
+ // マーカーがあれば、立方体を描画\r
+ if (this._is_marker_exist){\r
+ // マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。\r
+ // Projection transformation.\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadMatrixd(_camera_projection, 0);\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ // Viewing transformation.\r
+ _gl.glLoadIdentity();\r
+ // 変換行列を取得\r
+ _nya.getTransmationMatrix(transmat_result);\r
+ // 変換行列をOpenGL形式に変換\r
+ _glnya.toCameraViewRH(transmat_result, __display_wk);\r
+ _gl.glLoadMatrixd(__display_wk, 0);\r
+ \r
+ // All other lighting and geometry goes here.\r
+ drawCube();\r
+ }\r
+ }\r
+ Thread.sleep(1);// タスク実行権限を一旦渡す\r
+ }catch(Exception e){\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+ synchronized (this._sync_object) {\r
+ this._cap_image.setBuffer(i_buffer);\r
+ this._is_marker_exist =this._nya.detectMarkerLite(this._cap_image, 110);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
+ {\r
+ }\r
+\r
+ private final static String CARCODE_FILE = "../../Data/patt.hiro";\r
+\r
+ private final static String PARAM_FILE = "../../Data/camera_para.dat";\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ try {\r
+ NyARParam param = new NyARParam();\r
+ param.loadARParamFromFile(PARAM_FILE);\r
+ param.changeScreenSize(SCREEN_X, SCREEN_Y);\r
+\r
+ NyARCode code = new NyARCode(16, 16);\r
+ code.loadARPattFromFile(CARCODE_FILE);\r
+\r
+ new JavaSimpleLite(param, code);\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JOGL sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+\r
+package jp.nyatla.nyartoolkit.jogl.sample;\r
+\r
+import java.awt.event.*;\r
+import java.awt.*;\r
+import javax.media.*;\r
+import javax.media.opengl.*;\r
+import com.sun.opengl.util.Animator;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+/**\r
+ * simpleLiteの複数マーカー同時認識バージョン\r
+ * "Hiro"のマーカーと"人"のマーカーの混在環境で、Hiroのマーカー全てに\r
+ * 立方体を表示します。\r
+ */\r
+public class JavaSimpleLite2 implements GLEventListener, JmfCaptureListener\r
+{\r
+ private final String CARCODE_FILE1 = "../../Data/patt.hiro";\r
+\r
+ private final String CARCODE_FILE2 = "../../Data/patt.kanji";\r
+\r
+ private final String PARAM_FILE = "../../Data/camera_para.dat";\r
+\r
+ private final static int SCREEN_X = 640;\r
+\r
+ private final static int SCREEN_Y = 480;\r
+\r
+ private Animator _animator;\r
+\r
+ private GLNyARRaster_RGB _cap_image;\r
+\r
+ private JmfCaptureDevice _capture;\r
+\r
+ private GL _gl;\r
+\r
+ private NyARGLUtil _glnya;\r
+\r
+ //NyARToolkit関係\r
+ private NyARDetectMarker _nya;\r
+\r
+ private NyARParam _ar_param;\r
+ private double[] _camera_projection=new double[16];\r
+ /**\r
+ * 立方体を書く\r
+ *\r
+ */\r
+ void drawCube()\r
+ {\r
+ // Colour cube data.\r
+ int polyList = 0;\r
+ float fSize = 0.5f;//マーカーサイズに対して0.5倍なので、4cmの立方体\r
+ int f, i;\r
+ float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };\r
+ float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };\r
+ int cube_num_faces = 6;\r
+ short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };\r
+\r
+ if (polyList == 0) {\r
+ polyList = _gl.glGenLists(1);\r
+ _gl.glNewList(polyList, GL.GL_COMPILE);\r
+ _gl.glBegin(GL.GL_QUADS);\r
+ for (f = 0; f < cube_num_faces; f++)\r
+ for (i = 0; i < 4; i++) {\r
+ _gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);\r
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ }\r
+ _gl.glEnd();\r
+ _gl.glColor3f(0.0f, 0.0f, 0.0f);\r
+ for (f = 0; f < cube_num_faces; f++) {\r
+ _gl.glBegin(GL.GL_LINE_LOOP);\r
+ for (i = 0; i < 4; i++)\r
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ _gl.glEnd();\r
+ }\r
+ _gl.glEndList();\r
+ }\r
+\r
+ _gl.glPushMatrix(); // Save world coordinate system.\r
+ _gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.\r
+ _gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.\r
+ _gl.glDisable(GL.GL_LIGHTING); // Just use colours.\r
+ _gl.glCallList(polyList); // Draw the cube.\r
+ _gl.glPopMatrix(); // Restore world coordinate system.\r
+\r
+ }\r
+\r
+ public JavaSimpleLite2()\r
+ {\r
+ Frame frame = new Frame("Java simpleLite with NyARToolkit");\r
+\r
+ // 3Dを描画するコンポーネント\r
+ GLCanvas canvas = new GLCanvas();\r
+ frame.add(canvas);\r
+ canvas.addGLEventListener(this);\r
+ frame.addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+\r
+ frame.setVisible(true);\r
+ Insets ins = frame.getInsets();\r
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
+ }\r
+\r
+ public void init(GLAutoDrawable drawable)\r
+ {\r
+ _gl = drawable.getGL();\r
+ _gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+ //NyARToolkitの準備\r
+ try {\r
+ //キャプチャの準備\r
+ JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();\r
+ _capture=devlist.getDevice(0);\r
+ _capture.setCaptureFormat(SCREEN_X, SCREEN_Y,15f);\r
+ _capture.setOnCapture(this); \r
+ //NyARToolkitの準備\r
+ _ar_param = new NyARParam();\r
+ _ar_param.loadARParamFromFile(PARAM_FILE);\r
+ _ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);\r
+\r
+ //ARコードを2個ロード\r
+ double[] width = new double[] { 80.0, 80.0 };\r
+ NyARCode[] ar_codes = new NyARCode[2];\r
+ ar_codes[0] = new NyARCode(16, 16);\r
+ ar_codes[0].loadARPattFromFile(CARCODE_FILE1);\r
+ ar_codes[1] = new NyARCode(16, 16);\r
+ ar_codes[1].loadARPattFromFile(CARCODE_FILE2);\r
+ //GL対応のRGBラスタオブジェクト\r
+ this._cap_image = new GLNyARRaster_RGB(this._ar_param,_capture.getCaptureFormat());\r
+\r
+ this._nya = new NyARDetectMarker(this._ar_param, ar_codes, width, 2,this._cap_image.getBufferReader().getBufferType());\r
+ this._nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。\r
+ //NyARToolkit用の支援クラス\r
+ this._glnya = new NyARGLUtil(_gl);\r
+ //キャプチャ開始\r
+ this._capture.start();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ //カメラパラメータの計算\r
+ this._glnya.toCameraFrustumRH(_ar_param,_camera_projection);\r
+ \r
+ this._animator = new Animator(drawable);\r
+ this._animator.start();\r
+\r
+ }\r
+\r
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
+ {\r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
+ _gl.glViewport(0, 0, width, height);\r
+\r
+ //視体積の設定\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadIdentity();\r
+ //見る位置\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ _gl.glLoadIdentity();\r
+ }\r
+ private NyARTransMatResult __display_transmat_result=new NyARTransMatResult();\r
+ private double[] __display_wk=new double[16];\r
+ \r
+ public void display(GLAutoDrawable drawable)\r
+ {\r
+ NyARTransMatResult transmat_result=__display_transmat_result;\r
+\r
+ try {\r
+ if (!_cap_image.hasData()) {\r
+ return;\r
+ }\r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame. \r
+ //画像チェックしてマーカー探して、背景を書く\r
+ int found_markers;\r
+ synchronized (_cap_image) {\r
+ found_markers = _nya.detectMarkerLite(_cap_image, 110);\r
+ //背景を書く\r
+ _glnya.drawBackGround(_cap_image, 1.0);\r
+ }\r
+ //あったら立方体を書く\r
+ for (int i = 0; i < found_markers; i++) {\r
+ //1番のマーカーでなければ表示しない。\r
+ if (_nya.getARCodeIndex(i) != 0) {\r
+ continue;\r
+ }\r
+ //マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。\r
+ // Projection transformation.\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadMatrixd(_camera_projection, 0);\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ // Viewing transformation.\r
+ _gl.glLoadIdentity();\r
+ //変換行列を取得\r
+ _nya.getTransmationMatrix(i,transmat_result);\r
+ //変換行列をOpenGL形式に変換\r
+ _glnya.toCameraViewRH(transmat_result, __display_wk);\r
+ _gl.glLoadMatrixd(__display_wk, 0);\r
+\r
+ // All other lighting and geometry goes here.\r
+ drawCube();\r
+ }\r
+ Thread.sleep(1);//タスク実行権限を一旦渡す \r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ return;\r
+ }\r
+\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+ synchronized (_cap_image) {\r
+ _cap_image.setBuffer(i_buffer);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
+ {\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ new JavaSimpleLite2();\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JOGL sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jogl.sample;\r
+\r
+\r
+import java.awt.event.*;\r
+import java.awt.*;\r
+import java.util.Date;\r
+\r
+import javax.media.Buffer;\r
+import javax.media.opengl.*;\r
+\r
+import com.sun.opengl.util.*;\r
+import com.sun.opengl.util.j2d.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+import jp.nyatla.nyartoolkit.processor.*;\r
+\r
+/*\r
+\r
+\r
+*/\r
+\r
+\r
+public class SingleARMarker implements GLEventListener, JmfCaptureListener\r
+{\r
+ class TextPanel\r
+ {\r
+ private TextRenderer _tr;\r
+ public TextPanel(int i_size)\r
+ {\r
+ this._tr=new TextRenderer(new Font("SansSerif", Font.BOLD, 36));\r
+\r
+ }\r
+ public void draw(String i_str,float i_scale)\r
+ {\r
+ this._tr.begin3DRendering();\r
+ this._tr.setColor(1.0f, 0.2f, 0.2f, 0.8f);\r
+ this._tr.draw3D(i_str, 0f,0f,0f,i_scale);\r
+ this._tr.end3DRendering();\r
+ return;\r
+ }\r
+ } \r
+ /**\r
+ * 1個のRawBit-Idマーカを認識するロジッククラス。\r
+ * detectMarker関数の呼び出しに同期して、transmatとcurrent_idパラメタを更新します。\r
+ * \r
+ *\r
+ */\r
+ class MarkerProcessor extends SingleARMarkerProcesser\r
+ { \r
+ private Object _sync_object=new Object();\r
+ public NyARTransMatResult transmat=null;\r
+ public int current_code=-1;\r
+\r
+ public MarkerProcessor(NyARParam i_cparam,int i_raster_format) throws NyARException\r
+ {\r
+ //アプリケーションフレームワークの初期化\r
+ super();\r
+ initInstance(i_cparam,i_raster_format);\r
+ return;\r
+ }\r
+ protected void onEnterHandler(int i_code)\r
+ {\r
+ synchronized(this._sync_object){\r
+ current_code=i_code;\r
+ }\r
+ }\r
+ protected void onLeaveHandler()\r
+ {\r
+ synchronized(this._sync_object){\r
+ current_code=-1;\r
+ this.transmat=null;\r
+ }\r
+ return; \r
+ }\r
+\r
+ protected void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result)\r
+ {\r
+ synchronized(this._sync_object){\r
+ this.transmat=result;\r
+ } \r
+ }\r
+ }\r
+ \r
+ private final String CARCODE_FILE1 = "../../Data/patt.hiro";\r
+ \r
+ \r
+ private Animator _animator;\r
+ private GLNyARRaster_RGB _cap_image;\r
+ private JmfCaptureDevice _capture;\r
+\r
+ private GL _gl;\r
+ private NyARGLUtil _glnya;\r
+ private TextPanel _panel;\r
+\r
+\r
+ //NyARToolkit関係\r
+ private NyARParam _ar_param;\r
+\r
+ private double[] _camera_projection=new double[16];\r
+ \r
+ private Object _sync_object=new Object();\r
+ private MarkerProcessor _processor;\r
+ private NyARCode[] _code_table=new NyARCode[1];\r
+\r
+ public SingleARMarker(NyARParam i_cparam) throws NyARException\r
+ {\r
+ JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();\r
+ this._ar_param=i_cparam;\r
+\r
+ //キャプチャリソースの準備\r
+ this._capture=devlist.getDevice(0);\r
+ if(!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y,30.0f)){\r
+ throw new NyARException();\r
+ }\r
+ this._capture.setOnCapture(this);\r
+ this._cap_image = new GLNyARRaster_RGB(i_cparam,this._capture.getCaptureFormat()); \r
+\r
+ this._code_table[0]=new NyARCode(16,16);\r
+ this._code_table[0].loadARPattFromFile(CARCODE_FILE1);\r
+ //プロセッサの準備\r
+ this._processor=new MarkerProcessor(i_cparam,this._cap_image.getBufferReader().getBufferType());\r
+ this._processor.setARCodeTable(_code_table,16,80.0);\r
+ \r
+ //OpenGLフレームの準備(OpenGLリソースの初期化、カメラの撮影開始は、initコールバック関数内で実行)\r
+ Frame frame = new Frame("Java simpleLite with NyARToolkit");\r
+ GLCanvas canvas = new GLCanvas();\r
+ frame.add(canvas);\r
+ canvas.addGLEventListener(this);\r
+ frame.addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+ \r
+ //ウインドウサイズの調整\r
+ frame.setVisible(true);\r
+ Insets ins = frame.getInsets();\r
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
+ return;\r
+ }\r
+ public void init(GLAutoDrawable drawable)\r
+ {\r
+ this._panel = new TextPanel(100);\r
+\r
+\r
+ this._gl = drawable.getGL();\r
+ this._gl.glEnable(GL.GL_DEPTH_TEST);\r
+\r
+ this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+ //NyARToolkitの準備\r
+ try {\r
+ this._glnya = new NyARGLUtil(this._gl);\r
+ //カメラパラメータの計算\r
+ this._glnya.toCameraFrustumRH(this._ar_param,this._camera_projection);\r
+ //キャプチャ開始\r
+ this._capture.start();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ this._animator = new Animator(drawable);\r
+ this._animator.start();\r
+ return;\r
+ }\r
+\r
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
+ {\r
+ \r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
+ _gl.glViewport(0, 0, width, height);\r
+\r
+ //視体積の設定\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadIdentity();\r
+ //見る位置\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ _gl.glLoadIdentity();\r
+ }\r
+ private double[] __display_wk=new double[16];\r
+ \r
+ \r
+ public void display(GLAutoDrawable drawable)\r
+ {\r
+ NyARTransMatResult transmat_result = this._processor.transmat;\r
+ if (!_cap_image.hasData()) {\r
+ return;\r
+ }\r
+ // 背景を書く\r
+ this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.\r
+ this._glnya.drawBackGround(this._cap_image, 1.0); \r
+ if(this._processor.current_code<0 || transmat_result==null){\r
+ \r
+ }else{\r
+ try{\r
+ synchronized(this._sync_object){\r
+ // Projection transformation.\r
+ this._gl.glMatrixMode(GL.GL_PROJECTION);\r
+ this._gl.glLoadMatrixd(_camera_projection, 0);\r
+ this._gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ // Viewing transformation.\r
+ this._gl.glLoadIdentity();\r
+ // 変換行列をOpenGL形式に変換\r
+ this._glnya.toCameraViewRH(transmat_result, __display_wk);\r
+ this._gl.glLoadMatrixd(__display_wk, 0);\r
+ // All other lighting and geometry goes here.\r
+ this._gl.glPushMatrix();\r
+ this._gl.glDisable(GL.GL_LIGHTING);\r
+\r
+ \r
+ //マーカのXZ平面をマーカの左上、表示開始位置を10cm上空へ。\r
+ //くるーんくるん\r
+ Date d = new Date();\r
+ float r=(d.getTime()/50)%360;\r
+ this._gl.glRotatef(r,0f,0f,1.0f);\r
+ this._gl.glTranslatef(-1.0f,0f,1.0f);\r
+ this._gl.glRotatef(90,1.0f,0f,0f);\r
+ this._panel.draw("MarkerId:"+this._processor.current_code,0.01f);\r
+ this._gl.glPopMatrix();\r
+ }\r
+ Thread.sleep(1);// タスク実行権限を一旦渡す\r
+ }catch(Exception e){\r
+ e.printStackTrace();\r
+ }\r
+ } \r
+ return;\r
+\r
+ }\r
+ /**\r
+ * カメラデバイスからのコールバック\r
+ */\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+ synchronized (this._sync_object) {\r
+ this._cap_image.setBuffer(i_buffer);\r
+ //フレームワークに画像を転送\r
+ this._processor.detectMarker(this._cap_image);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
+ {\r
+ }\r
+\r
+\r
+ private final static int SCREEN_X = 640;\r
+ private final static int SCREEN_Y = 480;\r
+ private final static String PARAM_FILE = "../../Data/camera_para.dat";\r
+ //エントリポイント\r
+ public static void main(String[] args)\r
+ {\r
+ try{\r
+ NyARParam cparam= new NyARParam();\r
+ cparam.loadARParamFromFile(PARAM_FILE);\r
+ cparam.changeScreenSize(SCREEN_X, SCREEN_Y); \r
+ new SingleARMarker(cparam);\r
+ }catch(Exception e){\r
+ e.printStackTrace();\r
+ }\r
+ return;\r
+ }\r
+}\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JOGL sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jogl.sample;\r
+\r
+import jp.nyatla.nyartoolkit.nyidmarker.data.*;\r
+\r
+import java.awt.event.*;\r
+import java.awt.*;\r
+import java.util.Date;\r
+\r
+import javax.media.Buffer;\r
+import javax.media.opengl.*;\r
+\r
+import com.sun.opengl.util.*;\r
+import com.sun.opengl.util.j2d.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+import jp.nyatla.nyartoolkit.processor.*;\r
+\r
+\r
+class TextPanel\r
+{\r
+ private TextRenderer _tr;\r
+ public TextPanel(int i_size)\r
+ {\r
+ this._tr=new TextRenderer(new Font("SansSerif", Font.BOLD, 36));\r
+\r
+ }\r
+ public void draw(String i_str,float i_scale)\r
+ {\r
+ this._tr.begin3DRendering();\r
+ this._tr.setColor(1.0f, 0.2f, 0.2f, 0.8f);\r
+ this._tr.draw3D(i_str, 0f,0f,0f,i_scale);\r
+ this._tr.end3DRendering();\r
+ return;\r
+ }\r
+}\r
+\r
+/**\r
+ * 1個のRawBit-Idマーカを認識するロジッククラス。\r
+ * detectMarker関数の呼び出しに同期して、transmatとcurrent_idパラメタを更新します。\r
+ * \r
+ *\r
+ */\r
+class MarkerProcessor extends SingleNyIdMarkerProcesser\r
+{ \r
+ private Object _sync_object=new Object();\r
+ public NyARTransMatResult transmat=null;\r
+ public int current_id=-1;\r
+\r
+ public MarkerProcessor(NyARParam i_cparam,int i_raster_format) throws NyARException\r
+ {\r
+ //アプリケーションフレームワークの初期化\r
+ super();\r
+ initInstance(i_cparam,new NyIdMarkerDataEncoder_RawBit(),i_raster_format);\r
+ return;\r
+ }\r
+ /**\r
+ * アプリケーションフレームワークのハンドラ(マーカ出現)\r
+ */\r
+ protected void onEnterHandler(INyIdMarkerData i_code)\r
+ {\r
+ synchronized(this._sync_object){\r
+ NyIdMarkerData_RawBit code=(NyIdMarkerData_RawBit)i_code;\r
+ if(code.length>4){\r
+ //4バイト以上の時はint変換しない。\r
+ this.current_id=-1;//undefined_id\r
+ }else{\r
+ this.current_id=0;\r
+ //最大4バイト繋げて1個のint値に変換\r
+ for(int i=0;i<code.length;i++){\r
+ this.current_id=(this.current_id<<8)|code.packet[i];\r
+ }\r
+ }\r
+ this.transmat=null;\r
+ }\r
+ }\r
+ /**\r
+ * アプリケーションフレームワークのハンドラ(マーカ消滅)\r
+ */\r
+ protected void onLeaveHandler()\r
+ {\r
+ synchronized(this._sync_object){\r
+ this.current_id=-1;\r
+ this.transmat=null;\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * アプリケーションフレームワークのハンドラ(マーカ更新)\r
+ */\r
+ protected void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result)\r
+ {\r
+ synchronized(this._sync_object){\r
+ this.transmat=result;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+public class SingleNyIdMarker implements GLEventListener, JmfCaptureListener\r
+{\r
+ private Animator _animator;\r
+ private GLNyARRaster_RGB _cap_image;\r
+ private JmfCaptureDevice _capture;\r
+\r
+ private GL _gl;\r
+ private NyARGLUtil _glnya;\r
+ private TextPanel _panel;\r
+\r
+\r
+ //NyARToolkit関係\r
+ private NyARParam _ar_param;\r
+\r
+ private double[] _camera_projection=new double[16];\r
+ \r
+ private Object _sync_object=new Object();\r
+ private MarkerProcessor _processor;\r
+\r
+ public SingleNyIdMarker(NyARParam i_cparam) throws NyARException\r
+ {\r
+ JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();\r
+ this._ar_param=i_cparam;\r
+\r
+ //キャプチャリソースの準備\r
+ this._capture=devlist.getDevice(0);\r
+ if(!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y,30.0f)){\r
+ throw new NyARException();\r
+ }\r
+ this._capture.setOnCapture(this);\r
+ this._cap_image = new GLNyARRaster_RGB(i_cparam,this._capture.getCaptureFormat()); \r
+\r
+ //プロセッサの準備\r
+ this._processor=new MarkerProcessor(i_cparam,this._cap_image.getBufferReader().getBufferType());\r
+ this._processor.setMarkerWidth(100);\r
+ \r
+ //OpenGLフレームの準備(OpenGLリソースの初期化、カメラの撮影開始は、initコールバック関数内で実行)\r
+ Frame frame = new Frame("Java simpleLite with NyARToolkit");\r
+ GLCanvas canvas = new GLCanvas();\r
+ frame.add(canvas);\r
+ canvas.addGLEventListener(this);\r
+ frame.addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+ \r
+ //ウインドウサイズの調整\r
+ frame.setVisible(true);\r
+ Insets ins = frame.getInsets();\r
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
+ return;\r
+ }\r
+ public void init(GLAutoDrawable drawable)\r
+ {\r
+ this._panel = new TextPanel(100);\r
+\r
+\r
+ this._gl = drawable.getGL();\r
+ this._gl.glEnable(GL.GL_DEPTH_TEST);\r
+\r
+ this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+ //NyARToolkitの準備\r
+ try {\r
+ this._glnya = new NyARGLUtil(this._gl);\r
+ //カメラパラメータの計算\r
+ this._glnya.toCameraFrustumRH(this._ar_param,this._camera_projection);\r
+ //キャプチャ開始\r
+ this._capture.start();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ this._animator = new Animator(drawable);\r
+ this._animator.start();\r
+ return;\r
+ }\r
+\r
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
+ {\r
+ \r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
+ _gl.glViewport(0, 0, width, height);\r
+\r
+ //視体積の設定\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadIdentity();\r
+ //見る位置\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ _gl.glLoadIdentity();\r
+ }\r
+ private double[] __display_wk=new double[16];\r
+ \r
+ \r
+ public void display(GLAutoDrawable drawable)\r
+ {\r
+ NyARTransMatResult transmat_result = this._processor.transmat;\r
+ if (!_cap_image.hasData()) {\r
+ return;\r
+ }\r
+ // 背景を書く\r
+ this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.\r
+ this._glnya.drawBackGround(this._cap_image, 1.0); \r
+ if(this._processor.current_id<0 || transmat_result==null){\r
+ \r
+ }else{\r
+ try{\r
+ synchronized(this._sync_object){\r
+ // Projection transformation.\r
+ this._gl.glMatrixMode(GL.GL_PROJECTION);\r
+ this._gl.glLoadMatrixd(_camera_projection, 0);\r
+ this._gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ // Viewing transformation.\r
+ this._gl.glLoadIdentity();\r
+ // 変換行列をOpenGL形式に変換\r
+ this._glnya.toCameraViewRH(transmat_result, __display_wk);\r
+ this._gl.glLoadMatrixd(__display_wk, 0);\r
+ // All other lighting and geometry goes here.\r
+ this._gl.glPushMatrix();\r
+ this._gl.glDisable(GL.GL_LIGHTING);\r
+\r
+ \r
+ //マーカのXZ平面をマーカの左上、表示開始位置を10cm上空へ。\r
+ //くるーんくるん\r
+ Date d = new Date();\r
+ float r=(d.getTime()/50)%360;\r
+ this._gl.glRotatef(r,0f,0f,1.0f);\r
+ this._gl.glTranslatef(-1.0f,0f,1.0f);\r
+ this._gl.glRotatef(90,1.0f,0f,0f);\r
+ this._panel.draw("MarkerId:"+this._processor.current_id,0.01f);\r
+ this._gl.glPopMatrix();\r
+ }\r
+ Thread.sleep(1);// タスク実行権限を一旦渡す\r
+ }catch(Exception e){\r
+ e.printStackTrace();\r
+ }\r
+ } \r
+ return;\r
+\r
+ }\r
+ /**\r
+ * カメラデバイスからのコールバック\r
+ */\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+ synchronized (this._sync_object) {\r
+ this._cap_image.setBuffer(i_buffer);\r
+ //フレームワークに画像を転送\r
+ this._processor.detectMarker(this._cap_image);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
+ {\r
+ }\r
+\r
+\r
+ private final static int SCREEN_X = 640;\r
+ private final static int SCREEN_Y = 480;\r
+ private final static String PARAM_FILE = "../../Data/camera_para.dat";\r
+ //エントリポイント\r
+ public static void main(String[] args)\r
+ {\r
+ try{\r
+ NyARParam cparam= new NyARParam();\r
+ cparam.loadARParamFromFile(PARAM_FILE);\r
+ cparam.changeScreenSize(SCREEN_X, SCREEN_Y); \r
+ new SingleNyIdMarker(cparam);\r
+ }catch(Exception e){\r
+ e.printStackTrace();\r
+ }\r
+ return;\r
+ }\r
+}\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry path="" kind="src"/>\r
+ <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>\r
+ <classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/QuickTime/QTSystem/QTJava.zip" kind="lib"/>\r
+ <classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="/NyARToolkit.utils.qt" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="bin" kind="output"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolkit.sample.qt</name>\r
+ <comment></comment>\r
+ <projects>\r
+ <project>NyARToolKit</project>\r
+ <project>NyARToolkit.utils.qt</project>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+/*
+ * PROJECT: NyARToolkit QuickTime sample program.
+ * --------------------------------------------------------------------------------
+ * The MIT License
+ * Copyright (c) 2008 nyatla
+ * airmail(at)ebony.plala.or.jp
+ * http://nyatla.jp/nyartoolkit/
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+
+package jp.nyatla.nyartoolkit.qt.sample;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.qt.utils.*;
+import java.awt.*;
+import jp.nyatla.nyartoolkit.core.*;
+import jp.nyatla.nyartoolkit.core.param.NyARParam;
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
+import jp.nyatla.nyartoolkit.detector.NyARSingleDetectMarker;
+/**
+ * VFM+ARToolkitテストプログラム
+ * カメラから取り込んだデータからマーカーを検出して、一致度と変換行列を表示します。
+ */
+public class NyarToolkitLinkTest extends Frame implements QtCaptureListener
+{
+ private static final long serialVersionUID = 6154831884117789648L;
+
+ private final String CARCODE_FILE = "../../Data/patt.hiro";
+
+ private final String PARAM_FILE = "../../Data/camera_para.dat";
+
+ private QtCameraCapture capture;
+
+ private NyARSingleDetectMarker nya;
+
+ private QtNyARRaster_RGB raster;
+
+ private NyARTransMatResult trans_mat_result = new NyARTransMatResult();
+
+ public NyarToolkitLinkTest() throws NyARException, NyARException
+ {
+ setTitle("QtCaptureTest");
+ setBounds(0, 0, 320 + 64, 240 + 64);
+ //キャプチャの準備
+ capture = new QtCameraCapture(320, 240, 30f);
+ capture.setCaptureListener(this);
+
+ //NyARToolkitの準備
+ NyARParam ar_param = new NyARParam();
+ NyARCode ar_code = new NyARCode(16, 16);
+ ar_param.loadARParamFromFile(PARAM_FILE);
+ ar_param.changeScreenSize(320, 240);
+ raster = new QtNyARRaster_RGB(320, 240);
+ nya = new NyARSingleDetectMarker(ar_param, ar_code, 80.0,raster.getBufferReader().getBufferType());
+ ar_code.loadARPattFromFile(CARCODE_FILE);
+ //キャプチャイメージ用のラスタを準備
+ }
+
+ public void onUpdateBuffer(byte[] pixels)
+ {
+ try {
+ //キャプチャしたバッファをラスタにセット
+ raster.setBuffer(pixels);
+
+ //キャプチャしたイメージを表示用に加工
+ Image img = raster.createImage();
+
+ Graphics g = getGraphics();
+
+ //マーカー検出
+ boolean is_marker_exist = nya.detectMarkerLite(raster, 100);
+ if (is_marker_exist) {
+ //変換行列を取得
+ nya.getTransmationMatrix(this.trans_mat_result);
+ }
+ //情報を画面に書く
+ g.drawImage(img, 32, 32, this);
+ if (is_marker_exist) {
+ g.drawString("マーカー検出:" + nya.getConfidence(), 32, 50);
+ g.drawString("[m00]" + this.trans_mat_result.m00, 32, 50 + 16 * 1);
+ g.drawString("[m01]" + this.trans_mat_result.m01, 32, 50 + 16 * 2);
+ g.drawString("[m02]" + this.trans_mat_result.m02, 32, 50 + 16 * 3);
+ g.drawString("[m03]" + this.trans_mat_result.m03, 32, 50 + 16 * 4);
+ g.drawString("[m10]" + this.trans_mat_result.m10, 32, 50 + 16 * 5);
+ g.drawString("[m11]" + this.trans_mat_result.m11, 32, 50 + 16 * 6);
+ g.drawString("[m12]" + this.trans_mat_result.m12, 32, 50 + 16 * 7);
+ g.drawString("[m13]" + this.trans_mat_result.m13, 32, 50 + 16 * 8);
+ g.drawString("[m20]" + this.trans_mat_result.m20, 32, 50 + 16 * 9);
+ g.drawString("[m21]" + this.trans_mat_result.m21, 32, 50 + 16 * 10);
+ g.drawString("[m22]" + this.trans_mat_result.m22, 32, 50 + 16 * 11);
+ g.drawString("[m23]" + this.trans_mat_result.m23, 32, 50 + 16 * 12);
+
+ } else {
+ g.drawString("マーカー未検出:", 32, 100);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void startCapture()
+ {
+ try {
+ capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ NyarToolkitLinkTest mainwin = new NyarToolkitLinkTest();
+ mainwin.setVisible(true);
+ mainwin.startCapture();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * PROJECT: NyARToolkit QuickTime sample program.
+ * --------------------------------------------------------------------------------
+ * The MIT License
+ * Copyright (c) 2008 nyatla
+ * airmail(at)ebony.plala.or.jp
+ * http://nyatla.jp/nyartoolkit/
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+package jp.nyatla.nyartoolkit.qt.sample;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.qt.utils.*;
+
+import java.awt.*;
+/**
+ * QuickTimeキャプチャプログラム
+ *
+ */
+public class QtCaptureTest extends Frame implements QtCaptureListener
+{
+ private static final long serialVersionUID = -734697739607654631L;
+
+ public QtCaptureTest() throws NyARException
+ {
+ setTitle("QtCaptureTest");
+ setBounds(0, 0, 320 + 64, 240 + 64);
+ capture = new QtCameraCapture(320, 240, 30f);
+ capture.setCaptureListener(this);
+ //キャプチャイメージ用のラスタを準備
+ raster = new QtNyARRaster_RGB(320, 240);
+ }
+
+ private QtCameraCapture capture;
+
+ private QtNyARRaster_RGB raster;
+
+ public void onUpdateBuffer(byte[] pixels)
+ {
+ raster.setBuffer(pixels);
+ Image img = raster.createImage();
+ Graphics g = getGraphics();
+ g.drawImage(img, 32, 32, this);
+ }
+
+ private void startCapture()
+ {
+ try {
+ capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ QtCaptureTest mainwin = new QtCaptureTest();
+ mainwin.setVisible(true);
+ mainwin.startCapture();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry path="" kind="src"/>\r
+ <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>\r
+ <classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="/NyARToolkit.utils.jmf" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="/NyARToolkit.utils.jogl" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/Java/jre1.6.0_03/lib/jogl.jar" kind="lib"/>\r
+ <classpathentry path="bin" kind="output"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolkit.sandbox</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.analyzer.histgram;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+\r
+/**\r
+ * Pタイル法による閾値検出\r
+ * \r
+ */\r
+public class NyARHistgramAnalyzer_PTile\r
+{\r
+ private int _persentage;\r
+ public NyARHistgramAnalyzer_PTile(int i_persentage)\r
+ {\r
+ assert (0 <= i_persentage && i_persentage <= 50);\r
+ //初期化\r
+ this._persentage=i_persentage;\r
+ } \r
+ public int getThreshold(NyARHistgram i_histgram)\r
+ {\r
+ // 閾値ピクセル数確定\r
+ int th_pixcels = i_histgram.total_of_data * this._persentage / 100;\r
+\r
+ // 閾値判定\r
+ int i;\r
+ if (th_pixcels > 0) {\r
+ // 黒点基準\r
+ for (i = 0; i < 254; i++) {\r
+ th_pixcels -= i_histgram.data[i];\r
+ if (th_pixcels <= 0) {\r
+ break;\r
+ }\r
+ }\r
+ } else {\r
+ // 白点基準\r
+ for (i = 255; i > 1; i--) {\r
+ th_pixcels += i_histgram.data[i];\r
+ if (th_pixcels >= 0) {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ // 閾値の保存\r
+ return i;\r
+ }\r
+}\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasteranalyzer;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.stack.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+/**\r
+ * QRコードの4頂点候補を探そうとするクラス。\r
+ * 未完成\r
+ *\r
+ */\r
+public class NyARRasterDetector_QrCodeEdge\r
+{\r
+ private NyARIntRectStack _result;\r
+\r
+ public NyARRasterDetector_QrCodeEdge(int i_result_max)\r
+ {\r
+ this._result = new NyARIntRectStack(i_result_max);\r
+ return;\r
+ }\r
+\r
+ public NyARIntRectStack geResult()\r
+ {\r
+ return this._result;\r
+ }\r
+\r
+ private boolean check_w1(int i_w1)\r
+ {\r
+ return i_w1>=1; \r
+ }\r
+ private boolean check_b1(int i_b1)\r
+ {\r
+ return i_b1 >= 2; \r
+ }\r
+ private boolean check_w2(int i_b1,int i_w2)\r
+ {\r
+ int v=i_w2*100/i_b1;\r
+ return (30<=v && v<=170);\r
+ }\r
+ private boolean check_b2(int i_b1,int i_b2)\r
+ {\r
+ int v=i_b2*100/i_b1;\r
+ //条件:(b1)/2の2~4倍\r
+ return (200<=v && v<=400);\r
+ }\r
+ private boolean check_w3(int i_w2,int i_w3)\r
+ {\r
+ int v=i_w3*100/i_w2;\r
+ return (50<=v && v<=150);\r
+ }\r
+ private boolean check_b3(int i_b3,int i_b1)\r
+ {\r
+ int v=i_b3*100/i_b1;\r
+ return (50<=v && v<=150);\r
+ } \r
+ public void analyzeRaster(INyARRaster i_input) throws NyARException\r
+ {\r
+ INyARBufferReader buffer_reader=i_input.getBufferReader();\r
+ assert (buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8));\r
+\r
+ // 結果をクリア\r
+ this._result.clear();\r
+\r
+ NyARIntSize size = i_input.getSize();\r
+ int x = 0;\r
+ int w1, b1, w2, b2, w3, b3;\r
+ w1 = b1 = w2 = b2 = w3 = b3 = 0;\r
+\r
+ NyARIntRect item;\r
+ int[] raster_buf=(int[])buffer_reader.getBuffer();\r
+ int line_ptr;\r
+ int s_pos, b2_spos,b3_spos;\r
+ b2_spos=0;\r
+ for (int y = size.h - 1-8; y >= 8; y--) {\r
+ line_ptr = y*size.w;\r
+ x = size.w - 1;\r
+ s_pos=0;\r
+ int token_id=0;\r
+ while(x>=0){\r
+ switch(token_id){\r
+ case 0:\r
+ // w1の特定\r
+ w1 = 0;\r
+ for (; x >= 0; x--) {\r
+ if (raster_buf[line_ptr+x] == 0) {\r
+ // 検出条件確認:w1は2以上欲しいな。\r
+ if (!check_w1(w1)) {\r
+ // 条件不十分\r
+ continue;\r
+ }else{\r
+ // 検出→次段処理へ\r
+ token_id=1;\r
+ }\r
+ break;\r
+ }\r
+ w1++;\r
+ }\r
+ break;\r
+ case 1:\r
+ // b1の特定\r
+ b1 = 0;\r
+ s_pos = x;\r
+ for (; x >= 0; x--) {\r
+ if (raster_buf[line_ptr+x] > 0) {\r
+ // 検出条件確認:b1は1以上欲しいな。\r
+ if (!check_b1(b1)){\r
+ //条件不十分→白検出からやり直し\r
+ token_id=0;\r
+ }else{\r
+ // 検出→次段処理へ\r
+ token_id=2;\r
+ }\r
+ break;\r
+ }\r
+ b1++;\r
+ }\r
+ break;\r
+ case 2:\r
+ // w2の特定\r
+ w2 = 0;\r
+ for (; x >= 0; x--) {\r
+ if (raster_buf[line_ptr+x] == 0) {\r
+ // 検出条件確認:w2*10/b1は80-120以上欲しいな。\r
+ if (!check_w2(b1,w2)) {\r
+ //条件不十分→w2→w1として、b1を解析\r
+ w1=w2;\r
+ token_id=1;\r
+ }else{\r
+ // 検出→次段処理へ\r
+// w1=w2;\r
+// token_id=11;\r
+ token_id=3;\r
+ }\r
+ break;\r
+ }\r
+ w2++;\r
+ }\r
+ break;\r
+ case 3:\r
+ // b2の特定\r
+ b2 = 0;\r
+ b2_spos=x;\r
+ for (; x >= 0; x--) {\r
+ if (raster_buf[line_ptr+x] > 0){\r
+ //条件:(w1+b1)/2の2~4倍\r
+\r
+ if (!check_b2(b1,b2)) {\r
+ // b2->b1と仮定して解析しなおす。\r
+ if(check_w1(w2) && check_b1(b2)){\r
+ w1 = w2;\r
+ b1 = b2;\r
+ s_pos=b2_spos;\r
+ token_id=2;\r
+ }else{\r
+ \r
+ token_id=0;\r
+ }\r
+ }else{\r
+ // 検出→次段処理へ\r
+// token_id=10;\r
+ token_id=4;\r
+ }\r
+ break;\r
+ }\r
+ b2++;\r
+ }\r
+ break;\r
+ case 4:\r
+ // w3の特定\r
+ w3 = 0;\r
+ for (; x >= 0; x--) {\r
+ if (raster_buf[line_ptr+x] == 0){\r
+ if (!check_w3(w2,w3)) {\r
+ //w2→w1,b2->b1として解析しなおす。\r
+ if(check_w1(w2) && check_b1(b2)){\r
+ w1 = w2;\r
+ b1 = b2;\r
+ s_pos=b2_spos;\r
+ token_id=2;\r
+ }else{\r
+ token_id=0;\r
+ }\r
+ }else{\r
+ // 検出→次段処理へ\r
+// w1=w3;\r
+// token_id=10;\r
+ token_id=5;\r
+ }\r
+ break;\r
+ }\r
+ w3++;\r
+ }\r
+ break;\r
+ case 5:\r
+ // b3の特定\r
+ b3 = 0;\r
+ b3_spos=x;\r
+ for (; x >= 0; x--) {\r
+ if (raster_buf[line_ptr+x] > 0) {\r
+ // 検出条件確認\r
+ if (!check_b3(b3,b1)) {\r
+ if(check_w1(w2) && check_b1(b2)){\r
+ //条件不十分→b3->b1,w3->w1として再解析\r
+ w1=w3;\r
+ b1=b3;\r
+ s_pos=b3_spos;\r
+ token_id=2;\r
+ }else{\r
+ token_id=0;\r
+ }\r
+ }else{\r
+ // 検出→次段処理へ\r
+ token_id=10;\r
+ }\r
+ break;\r
+ }\r
+ b3++;\r
+ }\r
+ break;\r
+ case 10:\r
+ /* コード特定→保管 */\r
+ item = this._result.prePush();\r
+ item.x = x;\r
+ item.y = y;\r
+ item.w =s_pos-x;\r
+ item.h=0;\r
+ /* 最大個数? */\r
+ /* 次のコードを探す */\r
+ token_id=0;\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasteranalyzer.threshold;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.analyzer.raster.threshold.INyARRasterThresholdAnalyzer;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 微分ヒストグラム法による閾値検出\r
+ * \r
+ */\r
+public class NyARRasterThresholdAnalyzer_DiffHistgram implements INyARRasterThresholdAnalyzer\r
+{\r
+ private int _threshold;\r
+\r
+ public NyARRasterThresholdAnalyzer_DiffHistgram()\r
+ {\r
+ }\r
+\r
+ private int createHistgram(int[] in_buf,NyARIntSize i_size, int[] o_histgram) throws NyARException\r
+ {\r
+ int[][] fil1={\r
+ {-1,-2,-1},\r
+ { 0, 0, 0},\r
+ { 1, 2, 1}};\r
+\r
+ // ヒストグラムを作成\r
+ for (int i = 0; i < 256; i++) {\r
+ o_histgram[i] = 0;\r
+ }\r
+ int sam;\r
+ int sam1,sam2;\r
+ for (int y = 1; y < i_size.h-1; y++) {\r
+ for (int x = 1; x < i_size.w-1; x++) {\r
+ int v = in_buf[y* i_size.w+x];\r
+ sam1=sam2=0;\r
+ for(int yy=0;yy<3;yy++){\r
+ for(int xx=0;xx<3;xx++){\r
+ int v2=in_buf[(y+yy-1)* i_size.w+(x+xx-1)];\r
+ sam1+=v2*fil1[xx][yy];\r
+ sam2+=v2*fil1[yy][xx];\r
+ } \r
+ }\r
+ sam=sam1*sam1+sam2*sam2;\r
+ o_histgram[v]+=sam;\r
+ }\r
+ }\r
+ int th=0;\r
+ int max=o_histgram[0];\r
+ for(int i=1;i<256;i++){\r
+ if(max<o_histgram[i]){\r
+ th=i;\r
+ max=o_histgram[i];\r
+ }\r
+ }\r
+ return th;\r
+ }\r
+\r
+ public int analyzeRaster(INyARRaster i_input) throws NyARException\r
+ {\r
+ final INyARBufferReader buffer_reader=i_input.getBufferReader(); \r
+ assert (buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ int[] histgram = new int[256];\r
+ return createHistgram((int[])buffer_reader.getBuffer(),i_input.getSize(), histgram);\r
+ }\r
+\r
+ /**\r
+ * デバック用の関数です。 ヒストグラムをラスタに書き出します。\r
+ * \r
+ * @param i_output\r
+ * 書き出し先のラスタオブジェクト 256ピクセル以上の幅があること。\r
+ */\r
+ public void debugDrawHistgramMap(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+ {\r
+ INyARBufferReader in_buffer_reader=i_input.getBufferReader(); \r
+ INyARBufferReader out_buffer_reader=i_output.getBufferReader(); \r
+ assert (in_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ assert (out_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ NyARIntSize size = i_output.getSize();\r
+\r
+ int[] out_buf = (int[]) out_buffer_reader.getBuffer();\r
+ // 0で塗りつぶし\r
+ for (int y = 0; y < size.h; y++) {\r
+ for (int x = 0; x < size.w; x++) {\r
+ out_buf[y* size.w+x] = 0;\r
+ }\r
+ }\r
+ // ヒストグラムを計算\r
+ int[] histgram = new int[256];\r
+ int threshold = createHistgram((int[])in_buffer_reader.getBuffer(),i_input.getSize(), histgram);\r
+\r
+ // ヒストグラムの最大値を出す\r
+ int max_v = 0;\r
+ for (int i = 0; i < 255; i++) {\r
+ if (max_v < histgram[i]) {\r
+ max_v = histgram[i];\r
+ }\r
+ }\r
+ // 目盛り\r
+ for (int i = 0; i < size.h; i++) {\r
+ out_buf[i* size.w+0] = 128;\r
+ out_buf[i* size.w+128] = 128;\r
+ out_buf[i* size.w+255] = 128;\r
+ }\r
+ // スケーリングしながら描画\r
+ for (int i = 0; i < 255; i++) {\r
+ out_buf[(histgram[i] * (size.h - 1) / max_v)* size.w+i] = 255;\r
+ }\r
+ // 値\r
+ for (int i = 0; i < size.h; i++) {\r
+ out_buf[i* size.w+threshold] = 255;\r
+ }\r
+ return;\r
+ }\r
+\r
+ public int getThreshold()\r
+ {\r
+ return this._threshold;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.INyARRasterFilter;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * エッジ検出フィルタ 入力 BUFFERFORMAT_INT2D 出力 BUFFERFORMAT_INT2D\r
+ */\r
+public class NyARRasterFilter_Edge implements INyARRasterFilter\r
+{\r
+ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+ {\r
+ INyARBufferReader in_buffer_reader=i_input.getBufferReader(); \r
+ INyARBufferReader out_buffer_reader=i_output.getBufferReader(); \r
+ assert (in_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ assert (out_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+\r
+ int[] out_buf = (int[]) out_buffer_reader.getBuffer();\r
+ int[] in_buf = (int[]) in_buffer_reader.getBuffer();\r
+\r
+ int bp = 0;\r
+ NyARIntSize size = i_output.getSize();\r
+ for (int y = 1; y < size.h; y++) {\r
+ int prev = 128;\r
+ for (int x = 1; x < size.w; x++) {\r
+ int w = in_buf[y* size.w+x];\r
+ out_buf[y* size.w+x] = (Math.abs(w - prev) + Math.abs(w - in_buf[(y - 1)* size.w+x])) / 2;\r
+ prev = w;\r
+ bp += 3;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * 入力Aと入力Bの積を出力します。\r
+ * \r
+ */\r
+public class NyARRasterOperator_Mul\r
+{\r
+ private IdoFilterImpl _dofilterimpl;\r
+ public NyARRasterOperator_Mul(int i_raster_type) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8:\r
+ this._dofilterimpl=new IdoFilterImpl_INT1D_GRAY_8();\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ //\r
+ public void doFilter(INyARRaster i_input_a,INyARRaster i_input_b, INyARRaster i_output) throws NyARException\r
+ {\r
+ assert (i_input_a.getSize().isEqualSize(i_output.getSize()) == true);\r
+ assert (i_input_b.getSize().isEqualSize(i_output.getSize()) == true);\r
+ this._dofilterimpl.doFilter(i_input_a.getBufferReader(),i_input_b.getBufferReader(),i_output.getBufferReader(),i_output.getSize());\r
+ }\r
+ \r
+ abstract class IdoFilterImpl\r
+ {\r
+ int[] _window_ref;\r
+ public abstract void doFilter(INyARBufferReader i_input_a,INyARBufferReader i_input_b,INyARBufferReader i_output,NyARIntSize i_size) throws NyARException;\r
+ \r
+ }\r
+ class IdoFilterImpl_INT1D_GRAY_8 extends IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input_a,INyARBufferReader i_input_b,INyARBufferReader i_output,NyARIntSize i_size) throws NyARException\r
+ {\r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ int[] in_buf1 = (int[]) i_input_a.getBuffer();\r
+ int[] in_buf2 = (int[]) i_input_b.getBuffer();\r
+ for(int i=i_size.h*i_size.w-1;i>=0;i--)\r
+ {\r
+ out_buf[i]=(in_buf1[i]*in_buf2[i])>>8;\r
+ }\r
+ return;\r
+ }\r
+ } \r
+}
\ No newline at end of file
--- /dev/null
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARGrayscaleRaster;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * YCbCr変換したY成分を、RGBカラーベクトルの差が少いほど強度が落ちるようにしてグレースケールに変換します。\r
+ * sには減衰度数を設定します。\r
+ * 強度計算は以下のように行います。\r
+ * f(x):=exp(-x^2/s^2) 窓関数\r
+ * p :=Y*f(cr)*f(cb)\r
+ */\r
+public class NyARRasterFilter_Rgb2Gs_CbCrCut implements INyARRasterFilter_RgbToGs\r
+{\r
+ private IdoFilterImpl _dofilterimpl;\r
+ /**\r
+ * 1024倍した値\r
+ */\r
+ private int _window[]=new int[256];\r
+ public NyARRasterFilter_Rgb2Gs_CbCrCut(int i_raster_type,double i_sigma) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ this._dofilterimpl=new IdoFilterImpl_BYTE1D_B8G8R8_24();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ this._dofilterimpl._window_ref=this._window;\r
+ //windowの作成\r
+ for(int i=0;i<256;i++){\r
+ double p=((double)i-127.0)/127.0;\r
+ this._window[i]=(int)(1024*Math.exp(-p*p/(i_sigma*i_sigma)));\r
+ }\r
+ }\r
+ public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException\r
+ {\r
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+ this._dofilterimpl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize());\r
+ }\r
+ \r
+ abstract class IdoFilterImpl\r
+ {\r
+ int[] _window_ref;\r
+ public abstract void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException;\r
+ \r
+ }\r
+ class IdoFilterImpl_BYTE1D_B8G8R8_24 extends IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException\r
+ {\r
+ assert( i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24));\r
+ \r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ byte[] in_buf = (byte[]) i_input.getBuffer();\r
+ \r
+ int r,g,b;\r
+ int[] win=this._window_ref;\r
+\r
+ int bp = 0;\r
+ for (int y = 0; y < i_size.h; y++){\r
+ for (int x = 0; x < i_size.w; x++){\r
+ b=(in_buf[bp] & 0xff);\r
+ g=(in_buf[bp + 1] & 0xff);\r
+ r=(in_buf[bp + 2] & 0xff);\r
+ bp += 3;\r
+ int yv=(306*r+601*g+117 * b)>>10;//0<yv<255\r
+ int cr=(((-173 * r-339 * g + 512 *b))>>10)+127;//-127.5<=0<=127.5\r
+ int cb=((( 512 * r-429 * g - 83 *b))>>10)+127;//-127.5<=0<=127.5\r
+ out_buf[y*i_size.w+x]=(yv*(int)win[cr]*win[cb])>>20;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ } \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_RgbToGs;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public class NyARRasterFilter_Rgb2Gs_RgbOr implements INyARRasterFilter_RgbToGs\r
+{\r
+ public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException\r
+ {\r
+ INyARBufferReader in_buffer_reader=i_input.getBufferReader(); \r
+ INyARBufferReader out_buffer_reader=i_output.getBufferReader(); \r
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+\r
+ final int[] out_buf = (int[]) out_buffer_reader.getBuffer();\r
+ final byte[] in_buf = (byte[]) in_buffer_reader.getBuffer();\r
+\r
+ NyARIntSize size = i_output.getSize();\r
+ switch (in_buffer_reader.getBufferType()) {\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ convert24BitRgb(in_buf, out_buf, size);\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ return;\r
+ }\r
+\r
+ private void convert24BitRgb(byte[] i_in, int[] i_out, NyARIntSize i_size)\r
+ {\r
+ int bp = 0;\r
+ for (int y = 0; y < i_size.h; y++) {\r
+ for (int x = 0; x < i_size.w; x++) {\r
+ i_out[y*i_size.w+x] = ((i_in[bp] & 0xff) | (i_in[bp + 1] & 0xff) | (i_in[bp + 2] & 0xff));\r
+ bp += 3;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARI64Point2d;\r
+\r
+public class NyARFixedFloat16Point2d extends NyARI64Point2d\r
+{\r
+ public static NyARFixedFloat16Point2d[] createArray(int i_number)\r
+ {\r
+ NyARFixedFloat16Point2d[] ret=new NyARFixedFloat16Point2d[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARFixedFloat16Point2d();\r
+ }\r
+ return ret;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point3d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARI64Point3d;\r
+\r
+public class NyARFixedFloat16Point3d extends NyARI64Point3d\r
+{\r
+ /**\r
+ * 配列ファクトリ\r
+ * @param i_number\r
+ * @return\r
+ */\r
+ public static NyARFixedFloat16Point3d[] createArray(int i_number)\r
+ {\r
+ NyARFixedFloat16Point3d[] ret=new NyARFixedFloat16Point3d[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARFixedFloat16Point3d();\r
+ }\r
+ return ret;\r
+ }\r
+ public void copyTo(NyARDoublePoint3d i_to)\r
+ {\r
+ i_to.x=(double)this.x/0x10000;\r
+ i_to.y=(double)this.y/0x10000;\r
+ i_to.z=(double)this.z/0x10000;\r
+ return;\r
+ }\r
+ public void copyFrom(NyARDoublePoint3d i_from)\r
+ {\r
+ this.x=(long)(i_from.x*0x10000);\r
+ this.y=(long)(i_from.y*0x10000);\r
+ this.z=(long)(i_from.z*0x10000);\r
+ return;\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARI64Linear;\r
+\r
+public class NyARI64Linear\r
+{\r
+ public long rise;//y軸の増加量\r
+ public long run;//x軸の増加量\r
+ public long intercept;//切片\r
+ public final void copyFrom(NyARI64Linear i_source)\r
+ {\r
+ this.rise=i_source.rise;\r
+ this.run=i_source.run;\r
+ this.intercept=i_source.intercept;\r
+ return;\r
+ }\r
+ public static NyARI64Linear[] createArray(int i_number)\r
+ {\r
+ NyARI64Linear[] ret=new NyARI64Linear[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARI64Linear();\r
+ }\r
+ return ret;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARI64Point2d;\r
+\r
+public class NyARI64Point2d\r
+{\r
+ public long x;\r
+\r
+ public long y;\r
+ /**\r
+ * 配列ファクトリ\r
+ * @param i_number\r
+ * @return\r
+ */\r
+ public static NyARI64Point2d[] createArray(int i_number)\r
+ {\r
+ NyARI64Point2d[] ret=new NyARI64Point2d[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARI64Point2d();\r
+ }\r
+ return ret;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARI64Point3d;\r
+\r
+public class NyARI64Point3d\r
+{\r
+ public long x;\r
+ public long y;\r
+ public long z;\r
+ /**\r
+ * 配列ファクトリ\r
+ * @param i_number\r
+ * @return\r
+ */\r
+ public static NyARI64Point3d[] createArray(int i_number)\r
+ {\r
+ NyARI64Point3d[] ret=new NyARI64Point3d[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARI64Point3d();\r
+ }\r
+ return ret;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix33;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARFixedFloat16Matrix33;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARI64Matrix33;\r
+\r
+\r
+public class NyARFixedFloat16Matrix33 extends NyARI64Matrix33\r
+{\r
+ public void copyFrom(NyARDoubleMatrix33 i_matrix)\r
+ {\r
+ this.m00=(long)i_matrix.m00*0x10000;\r
+ this.m01=(long)i_matrix.m01*0x10000;\r
+ this.m02=(long)i_matrix.m02*0x10000;\r
+ this.m10=(long)i_matrix.m10*0x10000;\r
+ this.m11=(long)i_matrix.m11*0x10000;\r
+ this.m12=(long)i_matrix.m12*0x10000;\r
+ this.m20=(long)i_matrix.m20*0x10000;\r
+ this.m21=(long)i_matrix.m21*0x10000;\r
+ this.m22=(long)i_matrix.m22*0x10000;\r
+ return;\r
+ }\r
+ public static NyARFixedFloat16Matrix33[] createArray(int i_number)\r
+ {\r
+ NyARFixedFloat16Matrix33[] ret=new NyARFixedFloat16Matrix33[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARFixedFloat16Matrix33();\r
+ }\r
+ return ret;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARFixedFloat24Matrix33;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARI64Matrix33;\r
+\r
+\r
+public class NyARFixedFloat24Matrix33 extends NyARI64Matrix33\r
+{\r
+ public void copyFrom(NyARDoubleMatrix33 i_matrix)\r
+ {\r
+ this.m00=(long)i_matrix.m00*0x1000000;\r
+ this.m01=(long)i_matrix.m01*0x1000000;\r
+ this.m02=(long)i_matrix.m02*0x1000000;\r
+ this.m10=(long)i_matrix.m10*0x1000000;\r
+ this.m11=(long)i_matrix.m11*0x1000000;\r
+ this.m12=(long)i_matrix.m12*0x1000000;\r
+ this.m20=(long)i_matrix.m20*0x1000000;\r
+ this.m21=(long)i_matrix.m21*0x1000000;\r
+ this.m22=(long)i_matrix.m22*0x1000000;\r
+ return;\r
+ }\r
+ public void copyTo(NyARDoubleMatrix33 i_to)\r
+ {\r
+ i_to.m00=(double)this.m00/0x1000000;\r
+ i_to.m01=(double)this.m01/0x1000000;\r
+ i_to.m02=(double)this.m02/0x1000000;\r
+ i_to.m10=(double)this.m10/0x1000000;\r
+ i_to.m11=(double)this.m11/0x1000000;\r
+ i_to.m12=(double)this.m12/0x1000000;\r
+ i_to.m20=(double)this.m20/0x1000000;\r
+ i_to.m21=(double)this.m21/0x1000000;\r
+ i_to.m22=(double)this.m22/0x1000000;\r
+ return;\r
+ }\r
+ \r
+ public static NyARFixedFloat24Matrix33[] createArray(int i_number)\r
+ {\r
+ NyARFixedFloat24Matrix33[] ret=new NyARFixedFloat24Matrix33[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARFixedFloat24Matrix33();\r
+ }\r
+ return ret;\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+public class NyARI64Matrix22\r
+{\r
+ public long m00;\r
+ public long m01;\r
+ public long m10;\r
+ public long m11;\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARI64Matrix33;\r
+\r
+\r
+public class NyARI64Matrix33\r
+{\r
+ public long m00;\r
+ public long m01;\r
+ public long m02;\r
+ public long m10;\r
+ public long m11;\r
+ public long m12;\r
+ public long m20;\r
+ public long m21;\r
+ public long m22;\r
+ public static NyARI64Matrix33[] createArray(int i_number)\r
+ {\r
+ NyARI64Matrix33[] ret=new NyARI64Matrix33[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARI64Matrix33();\r
+ }\r
+ return ret;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.sandbox.qrcode;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabelStack;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabeling_ARToolKit;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.ContourPickup;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.Coord2Linear;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public class NyARQrCodeDetector implements INyARSquareContourDetector\r
+{\r
+ private NyARQrCodeSymbolBinder _binder;\r
+\r
+ private static final int AR_AREA_MAX = 10000;\r
+\r
+ private static final int AR_AREA_MIN = 50;\r
+\r
+ private final int _width;\r
+\r
+ private final int _height;\r
+\r
+ private final NyARLabeling_ARToolKit _labeling;\r
+\r
+ private final NyARLabelingImage _limage;\r
+\r
+ private final Coord2Linear _sqconvertor;\r
+ private final ContourPickup _cpickup=new ContourPickup();\r
+ \r
+ /**\r
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARQrCodeDetector(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException\r
+ {\r
+ this._width = i_size.w;\r
+ this._height = i_size.h;\r
+ this._labeling = new NyARLabeling_ARToolKit();\r
+ this._limage = new NyARLabelingImage(this._width, this._height);\r
+ this._binder=new NyARQrCodeSymbolBinder(i_dist_factor_ref);\r
+ this._sqconvertor=new Coord2Linear(i_size,i_dist_factor_ref);\r
+\r
+ // 輪郭の最大長はMAX_COORD_NUMの2倍に制限\r
+ int number_of_coord = MAX_COORD_NUM* 2;\r
+\r
+ // 輪郭バッファはnumber_of_coordの2倍\r
+ this._max_coord = number_of_coord;\r
+ this._xcoord = new int[number_of_coord * 2];\r
+ this._ycoord = new int[number_of_coord * 2];\r
+ \r
+ }\r
+\r
+ private final int _max_coord;\r
+\r
+ private final int[] _xcoord;\r
+\r
+ private final int[] _ycoord;\r
+\r
+\r
+ /**\r
+ * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double\r
+ * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。\r
+ * \r
+ * @param i_raster\r
+ * 解析する2値ラスタイメージを指定します。\r
+ * @param o_square_stack\r
+ * 抽出した正方形候補を格納するリスト\r
+ * @throws NyARException\r
+ */\r
+ public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
+ {\r
+ final NyARLabelingImage limage = this._limage;\r
+\r
+ // 初期化\r
+\r
+ // マーカーホルダをリセット\r
+ o_square_stack.clear();\r
+\r
+ // ラベリング\r
+ this._labeling.labeling(i_raster,limage);\r
+\r
+ // ラベル数が0ならここまで\r
+ final int label_num = limage.getLabelStack().getLength();\r
+ if (label_num < 1) {\r
+ return;\r
+ }\r
+\r
+ final NyARLabelingLabelStack stack = limage.getLabelStack();\r
+ // ラベルを大きい順に整列\r
+ stack.sortByArea();\r
+\r
+ final NyARLabelingLabel[] labels = stack.getArray();\r
+ // デカいラベルを読み飛ばし\r
+ int i;\r
+ for (i = 0; i < label_num; i++) {\r
+ // 検査対象内のラベルサイズになるまで無視\r
+ if (labels[i].area <= AR_AREA_MAX) {\r
+ break;\r
+ }\r
+ }\r
+ \r
+ final int xsize = this._width;\r
+ final int ysize = this._height;\r
+ final int[] xcoord = this._xcoord;\r
+ final int[] ycoord = this._ycoord;\r
+ final int coord_max = this._max_coord;\r
+ final int[] buf = (int[]) limage.getBufferReader().getBuffer();\r
+ final int[] indextable = limage.getIndexArray();\r
+\r
+ int label_area;\r
+ NyARLabelingLabel label_pt;\r
+ NyARSquareStack wk_stack=new NyARSquareStack(10);\r
+ wk_stack.clear();\r
+\r
+ for (; i < label_num; i++) {\r
+ label_pt = labels[i];\r
+ label_area = label_pt.area;\r
+ // 検査対象サイズよりも小さくなったら終了\r
+ if (label_area < AR_AREA_MIN) {\r
+ break;\r
+ }\r
+ // クリップ領域が画面の枠に接していれば除外\r
+ if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){\r
+ continue;\r
+ }\r
+ if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){\r
+ continue;\r
+ }\r
+ // 特徴点候補であるかを確認する。\r
+ if (!hasQrEdgeFeature(buf, indextable, label_pt)) {\r
+ continue;\r
+ }\r
+ // 輪郭を取得\r
+ final int coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
+ if (coord_num == coord_max) {\r
+ // 輪郭が大きすぎる。\r
+ continue;\r
+ }\r
+ //輪郭分析用に正規化する。\r
+ final int vertex1 = Coord2Linear.normalizeCoord(xcoord, ycoord, coord_num);\r
+\r
+ //ここから先が輪郭分析\r
+ NyARSquare square_ptr = o_square_stack.prePush();\r
+ if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
+ o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
+ continue; \r
+ }\r
+ }\r
+ //シンボルの関連付け\r
+ bindQrcodeEdge(wk_stack,o_square_stack);\r
+ //エッジ同士の相関関係をしらべる。\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * QRコードのエッジグループを作る\r
+ * @param i_square_stack\r
+ */\r
+ public void bindQrcodeEdge(NyARSquareStack i_square_stack,NyARSquareStack o_square_stack) throws NyARException\r
+ {\r
+ NyARSquare[] group=new NyARSquare[3];\r
+ int number_of_edge=i_square_stack.getLength();\r
+ if(number_of_edge<3){\r
+ return;\r
+ }\r
+ NyARSquare[] sa=i_square_stack.getArray();\r
+ for(int i=0;i<number_of_edge-2;i++)\r
+ { \r
+ group[0]=sa[i];\r
+ for(int i2=i+1;i2<number_of_edge-1;i2++)\r
+ {\r
+ group[1]=sa[i2];\r
+ for(int i3=i2+1;i3<number_of_edge;i3++){\r
+ group[2]=sa[i3];\r
+ //3個のエッジの関連性を確認する。\r
+ NyARSquare new_square=(NyARSquare)o_square_stack.prePush();\r
+ if(!this._binder.composeSquare(group,new_square)){\r
+ o_square_stack.pop();\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ private static int MAX_COORD_NUM=(320+240)*2;//サイズの1/2の長方形の編程度が目安(VGAなら(320+240)*2)\r
+\r
+ /**\r
+ * QRコードのシンボル特徴を持つラベルであるかを調べる\r
+ * @param buf\r
+ * @param index_table\r
+ * @param i_label\r
+ * @return\r
+ */\r
+ private boolean hasQrEdgeFeature(int[] buf, int[] index_table, NyARLabelingLabel i_label)\r
+ {\r
+ int tx, bx;\r
+ int w;\r
+ int i_label_id = i_label.id;\r
+ int limage_j_ptr;\r
+ final int clip_l = i_label.clip_l;\r
+ final int clip_b = i_label.clip_b;\r
+ final int clip_r = i_label.clip_r;\r
+ final int clip_t = i_label.clip_t;\r
+\r
+ tx = bx = 0;\r
+ // 上接点(→)\r
+ limage_j_ptr = clip_t*this._width;\r
+ for (int i = clip_l; i <= clip_r; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {\r
+ w = buf[limage_j_ptr+i];\r
+ if (w > 0 && index_table[w - 1] == i_label_id) {\r
+ tx = i;\r
+ break;\r
+ }\r
+ }\r
+ // 下接点(←)\r
+ limage_j_ptr = clip_b*this._width;\r
+ for (int i = clip_r; i >= clip_l; i--) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {\r
+ w = buf[limage_j_ptr+i];\r
+ if (w > 0 && index_table[w - 1] == i_label_id) {\r
+ bx = i;\r
+ break;\r
+ }\r
+ }\r
+ final int cx = (clip_l + clip_r) / 2;\r
+ final int cy = (clip_t + clip_b) / 2;\r
+ // 横断チェック(中心から線を引いて、010になるかしらべる)\r
+ if (!checkDiagonalLine(buf, cx, cy, bx, clip_b)) {\r
+ return false;\r
+ }\r
+ if (!checkDiagonalLine(buf, tx, clip_t, cx, cy)) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * シンボルのパターン特徴を調べる関数\r
+ * 対角線の一部が010になってるか調べる。\r
+ * \r
+ * @param buf\r
+ * @param i_px1\r
+ * @param i_py1\r
+ * @param i_px2\r
+ * @param i_py2\r
+ * @return\r
+ */\r
+ private boolean checkDiagonalLine(int[] buf, int i_px1, int i_py1, int i_px2, int i_py2)\r
+ {\r
+ int sub_y = i_py2 - i_py1;\r
+ int sub_x = i_px2 - i_px1;\r
+ // 黒\r
+ int i = 0;\r
+ for (; i < sub_y; i++) {\r
+ int yp = i_py1 + i;\r
+ int xp = i_px1 + i * sub_x / sub_y;\r
+ if (buf[yp*this._width+xp] == 0 && buf[yp*this._width+(xp-1)] == 0 && buf[yp*this._width+(xp+1)] == 0) {\r
+ break;\r
+ }\r
+\r
+ }\r
+ if (i == sub_y) {\r
+ return false;\r
+ }\r
+ // 白\r
+ for (; i < sub_y; i++) {\r
+ int yp = i_py1 + i;\r
+ int xp = i_px1 + i * sub_x / sub_y;\r
+ if (buf[yp*this._width+xp] != 0 && buf[yp*this._width+(xp-1)] != 0 && buf[yp*this._width+(xp+1)] != 0) {\r
+ break;\r
+ }\r
+\r
+ }\r
+ if (i == sub_y) {\r
+ return false;\r
+ }\r
+ // 黒\r
+ for (; i < sub_y; i++) {\r
+ int yp = i_py1 + i;\r
+ int xp = i_px1 + i * sub_x / sub_y;\r
+ if (buf[yp*this._width+xp] == 0 && buf[yp*this._width+(xp-1)] == 0 && buf[yp*this._width+(xp+1)] == 0) {\r
+ break;\r
+ }\r
+\r
+ }\r
+ if (i != sub_y) {\r
+ return false;\r
+ }\r
+ // 端まで到達したらOK\r
+ return true;\r
+ }\r
+\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.sandbox.qrcode;\r
+\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+/**\r
+ * QRコードのシンボルを結びつける偉いクラス\r
+ * アルゴリズムはこんな感じ。\r
+ * 1.3シンボルの位置関係から中間のシンボルを探す。\r
+ * 2.中間シンボルの内角点を探す\r
+ * 3.残りの2シンボル間の最短距離の頂点セットを見つけて、それぞれの内角点を探す\r
+ * 4.3個の内角点が決まったら、各シンボルごとに外角点(反対側の頂点)を特定する。\r
+ * 5.対角のシンボルの外角頂点から伸びる線分を合成して、矩形を決める。\r
+ * 6.矩形が決まったら、方程式を解いて交点を出して、頂点にする。\r
+ * 7.交点と中央のシンボルの位置関係から、正しい計算が行われたかを判定(まだ実装してない)\r
+ * \r
+ * \r
+ * この方法は浅い角度でシンボル集合を見たときに、1や3の手順が高い確率で失敗する。\r
+ * その場合計算が途中で破綻するのでわかる(はず)\r
+ * 他の方法もあるけど、それはまた今度。\r
+ */\r
+public class NyARQrCodeSymbolBinder\r
+{\r
+ private NyARCameraDistortionFactor _distfactor;\r
+\r
+ public NyARQrCodeSymbolBinder(NyARCameraDistortionFactor i_ref_distortion)\r
+ {\r
+ this._distfactor=i_ref_distortion;\r
+ return;\r
+ }\r
+ /**\r
+ * 最小の三角形を構成する頂点セットを得る\r
+ * @param i_s0\r
+ * @param i_s1\r
+ * @param i_s2\r
+ * @param o_vertex\r
+ */\r
+ private static void getMinimumTriangleVertex(NyARSquare[] i_sqare,int[] o_vertex_id)\r
+ {\r
+ //辺の長さが最小になる頂点の組合せを探す\r
+ int d;\r
+ int x,y;\r
+ int dmax=0x7fffffff;\r
+ final NyARIntPoint2d[] vertex0=i_sqare[0].imvertex;\r
+ final NyARIntPoint2d[] vertex1=i_sqare[1].imvertex;\r
+ final NyARIntPoint2d[] vertex2=i_sqare[2].imvertex;\r
+ for(int i=0;i<4;i++)\r
+ {\r
+ for(int i2=0;i2<4;i2++)\r
+ {\r
+ for(int i3=0;i3<4;i3++){\r
+ x=vertex0[i].x-vertex2[i3].x;\r
+ y=vertex0[i].y-vertex2[i3].y;\r
+ d=x*x+y*y;\r
+ x=vertex1[i2].x-vertex2[i3].x;\r
+ y=vertex1[i2].y-vertex2[i3].y;\r
+ d+=x*x+y*y;\r
+ x=vertex1[i2].x-vertex0[i].x;\r
+ y=vertex1[i2].y-vertex0[i].y;\r
+ d+=x*x+y*y;\r
+ if(d<dmax){\r
+ dmax=d;\r
+ o_vertex_id[0]=i; \r
+ o_vertex_id[1]=i2;\r
+ o_vertex_id[2]=i3;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * 2矩形の頂点距離が最低の組合せを探す\r
+ * @param i_sqare\r
+ * @param o_vertex_id\r
+ */\r
+ private static void getMinimumLineVertex(NyARIntPoint2d[] i_sqare0,NyARIntPoint2d[] i_sqare1,int[] o_vertex_id)\r
+ {\r
+ //辺の長さが最小になる頂点の組合せを探す\r
+ int d;\r
+ int x,y;\r
+ int dmax=0x7fffffff;\r
+ for(int i=0;i<4;i++)\r
+ {\r
+ for(int i2=0;i2<4;i2++)\r
+ {\r
+ x=i_sqare1[i2].x-i_sqare0[i].x;\r
+ y=i_sqare1[i2].y-i_sqare0[i].y;\r
+ d=x*x+y*y;\r
+ if(d<dmax){\r
+ dmax=d;\r
+ o_vertex_id[0]=i; \r
+ o_vertex_id[1]=i2;\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * シンボルグループの重心を計算する\r
+ * @param i_sqare\r
+ * @param i_center\r
+ */\r
+ private void getSymbolGroupCenter(NyARSquare[] i_sqare,NyARIntPoint2d i_center)\r
+ {\r
+ //シンボルグループの重心を計算\r
+ int cx,cy;\r
+ cx=cy=0;\r
+ for(int i=0;i<3;i++)\r
+ {\r
+ final NyARIntPoint2d[] sq_ptr=i_sqare[i].imvertex;\r
+ cx+=sq_ptr[0].x; \r
+ cx+=sq_ptr[1].x; \r
+ cx+=sq_ptr[2].x; \r
+ cx+=sq_ptr[3].x; \r
+ cy+=sq_ptr[0].y; \r
+ cy+=sq_ptr[1].y; \r
+ cy+=sq_ptr[2].y; \r
+ cy+=sq_ptr[3].y; \r
+ }\r
+ i_center.x=cx/12;\r
+ i_center.y=cy/12; \r
+ return;\r
+ }\r
+ /**\r
+ * キーシンボルのインデックスを得る\r
+ * @param i_sqare\r
+ * @param i_vertex_id\r
+ * 最小三角形の頂点IDセット\r
+ * @return\r
+ */\r
+ private static int getKeySymble(NyARSquare[] i_sqare,NyARIntPoint2d i_center,int[] i_vertex_id)\r
+ {\r
+ //シンボルグループの重心を計算\r
+ final int cx=i_center.x;\r
+ final int cy=i_center.y; \r
+ //前段で探した頂点候補のうち、最も重心に近いものが中心シンボルの内対角点\r
+ int key_symble_idx=0;\r
+ int x=i_sqare[0].imvertex[i_vertex_id[0]].x-cx;\r
+ int y=i_sqare[0].imvertex[i_vertex_id[0]].y-cy;\r
+ int dmax=x*x+y*y;\r
+ for(int i=1;i<3;i++){\r
+ x=i_sqare[i].imvertex[i_vertex_id[i]].x-cx;\r
+ y=i_sqare[i].imvertex[i_vertex_id[i]].y-cy;\r
+ final int d=x*x+y*y;\r
+ if(d<dmax){\r
+ dmax=d;\r
+ key_symble_idx=i;\r
+ }\r
+ }\r
+ return key_symble_idx;\r
+ }\r
+ private NyARDoublePoint2d __bindSquare_ideal_vertex=new NyARDoublePoint2d();\r
+ /**\r
+ * 2つの対角にある矩形から、それらを対角とする矩形を作る。\r
+ * @param i_sq1\r
+ * @param i_lv1\r
+ * @param i_sq2\r
+ * @param i_lv2\r
+ */\r
+ private void bindSquare(NyARSquare i_sq1,int i_lv1,NyARSquare i_sq2,int i_lv2,NyARSquare o_qr_square)\r
+ {\r
+ //4辺の式を計算\r
+ o_qr_square.line[0].copyFrom(i_sq1.line[(i_lv1+3)%4]);\r
+ o_qr_square.line[1].copyFrom(i_sq1.line[(i_lv1+0)%4]);\r
+ o_qr_square.line[2].copyFrom(i_sq2.line[(i_lv2+3)%4]);\r
+ o_qr_square.line[3].copyFrom(i_sq2.line[(i_lv2+0)%4]);\r
+ //歪み無しの座標系を計算\r
+ final NyARDoublePoint2d[] l_sqvertex = o_qr_square.sqvertex;\r
+ final NyARIntPoint2d[] imvertex_ptr = o_qr_square.imvertex;\r
+\r
+ final NyARLinear[] l_line = o_qr_square.line;\r
+ final NyARDoublePoint2d ideal_vertex=this.__bindSquare_ideal_vertex;\r
+ for (int i = 0; i < 4; i++) {\r
+ final NyARLinear l_line_i = l_line[i];\r
+ final NyARLinear l_line_2 = l_line[(i + 3) % 4];\r
+ final double w1 = l_line_2.dy * l_line_i.dx - l_line_i.dy * l_line_2.dx;\r
+ if (w1 == 0.0) {\r
+ return;\r
+ }\r
+ l_sqvertex[i].x = (l_line_2.dx * l_line_i.c - l_line_i.dx * l_line_2.c) / w1;\r
+ l_sqvertex[i].y = (l_line_i.dy * l_line_2.c - l_line_2.dy * l_line_i.c) / w1;\r
+ _distfactor.ideal2Observ(l_sqvertex[i], ideal_vertex);\r
+ //Ideal→observに変換して、画面上の座標とする。\r
+ imvertex_ptr[i].x=(int)l_sqvertex[i].x;\r
+ imvertex_ptr[i].y=(int)l_sqvertex[i].y;\r
+ } \r
+// Graphics g=this.bimg.getGraphics();\r
+// g.setColor(Color.red);\r
+// int[] x=new int[4];\r
+// int[] y=new int[4];\r
+// for(int i=0;i<4;i++){\r
+// x[i]=(int)l_sqvertex[i].x;\r
+// y[i]=(int)l_sqvertex[i].y;\r
+// }\r
+// g.drawPolygon(x,y,4);\r
+ return;\r
+ //基準点はVertexをそのまま採用\r
+ //2個の想定点は座標を逆変換して設定\r
+ }\r
+ /**\r
+ * directionはキーシンボルのインデックスでARToolKitの頂点座標じゃないので注意すること。\r
+ * @param i_sq\r
+ * @param o_sq\r
+ * @return\r
+ */\r
+ public boolean composeSquare(NyARSquare[] i_sq,NyARSquare o_sq)\r
+ {\r
+ int[] minimum_triangle_vertex=new int[3];\r
+ int[] minimum_line_vertex=new int[2];\r
+ \r
+ NyARIntPoint2d center=new NyARIntPoint2d();\r
+\r
+ //辺の長さが最小になる頂点の組合せを探す\r
+ getMinimumTriangleVertex(i_sq,minimum_triangle_vertex);\r
+ \r
+ //中心位置を計算する。\r
+ getSymbolGroupCenter(i_sq,center);\r
+ \r
+ //キーシンボルのインデクス番号を得る\r
+ int key_simble_idx=getKeySymble(i_sq,center,minimum_triangle_vertex);\r
+ \r
+ //対角シンボルのインデックス番号を決める\r
+ int symbol_e1_idx=(key_simble_idx+1)%3;\r
+ int symbol_e2_idx=(key_simble_idx+2)%3;\r
+ \r
+ //対角シンボル間で最短距離を取る頂点ペアを取る\r
+ //(角度を低くするとエラーが出やすい。対角線との類似性を確認する方法のほうがいい。多分)\r
+ getMinimumLineVertex(i_sq[symbol_e1_idx].imvertex,i_sq[symbol_e2_idx].imvertex,minimum_line_vertex);\r
+ \r
+ //内対角を外対角に変換\r
+ int lv1=(minimum_line_vertex[0]+2)%4;\r
+ int lv2=(minimum_line_vertex[1]+2)%4;\r
+ int kv =(minimum_triangle_vertex[key_simble_idx]+2)%4;\r
+ //矩形の合成\r
+ bindSquare(i_sq[symbol_e1_idx],lv1,i_sq[symbol_e2_idx],lv2,o_sq);\r
+ \r
+ //方位判定 \r
+ int direction=getDirection(o_sq,i_sq[key_simble_idx].imvertex[kv],center);\r
+ if(direction==-1){\r
+ return false;\r
+ }\r
+ o_sq.direction=direction;\r
+ \r
+ return true;\r
+ } \r
+ /**\r
+ * この関数はあんまり頂点ズレがひどいと失敗する\r
+ * @param i_square\r
+ * @param i_vertex\r
+ * @param i_center\r
+ * @return\r
+ */\r
+ private int getDirection(NyARSquare i_square,NyARIntPoint2d i_vertex,NyARIntPoint2d i_center)\r
+ {\r
+ //開始点(中央シンボル)までの頂点のシフト数を決める\r
+ int x,y;\r
+ x=i_square.imvertex[0].x-i_vertex.x;\r
+ y=i_square.imvertex[0].y-i_vertex.y;\r
+ int v1=x*x+y*y;\r
+ x=i_square.imvertex[2].x-i_vertex.x;\r
+ y=i_square.imvertex[2].y-i_vertex.y;\r
+ int v2=x*x+y*y;\r
+ int shift;\r
+ int v;\r
+ if(v1<v2){\r
+ shift=0;\r
+ v=v1;\r
+ }else{\r
+ shift=2;\r
+ v=v2;\r
+ }\r
+ //小さい方の対角線が64(8x8)より大きくずれてたら認識ミスとみなす\r
+ if(v>64){\r
+ return -1;\r
+ }\r
+ //シンボルがどの象限にあるか確認する\r
+ x=i_vertex.x=i_center.x;\r
+ y=i_vertex.y=i_center.y;\r
+ int dir;\r
+ if(x<0){\r
+ dir=2;//dir=y<0?1:2;\r
+ }else{\r
+ dir=4;//dir=y<0?3:4;\r
+ }\r
+ return (dir+shift)%4;\r
+ }\r
+ \r
+ \r
+ \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.qrcode;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 平均移動法を使った2値化フィルタ\r
+ * \r
+ */\r
+public class NyARRasterFilter_QrAreaAverage implements INyARRasterFilter_GsToBin\r
+{\r
+ private int _area = 8;\r
+\r
+ public void doFilter(NyARGrayscaleRaster i_input, NyARBinRaster i_output) throws NyARException\r
+ {\r
+ final NyARIntSize size = i_output.getSize();\r
+ final int[] out_buf = (int[]) i_output.getBufferReader().getBuffer();\r
+ final int[] in_buf = (int[]) i_input.getBufferReader().getBuffer();\r
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+ assert (size.h % 8 == 0 && size.w % 8 == 0);//暫定実装なので。\r
+\r
+ final int area = this._area;\r
+ int y1 = area;\r
+ int x1 = area;\r
+ int y2 = size.h - area;\r
+ int x2 = size.w - area;\r
+\r
+ for (int y = y1; y < y2; y++) {\r
+ int sum, nn;\r
+ sum = nn = 0;\r
+ for (int yy = y - area; yy < y + area + 1; yy++) {\r
+ for (int xx = x1 - area; xx < x1 + area; xx++) {\r
+ sum += in_buf[yy*size.w+xx];\r
+ nn++;\r
+ }\r
+ }\r
+ int th;\r
+ boolean first = true;\r
+ th=0;\r
+ for (int x = area; x < x2; x++) {\r
+ if (!first) {\r
+ for (int yy = y - area; yy < y + area; yy++) {\r
+ sum += in_buf[yy*size.w+x + area];\r
+ sum -= in_buf[yy*size.w+x - area];\r
+ }\r
+ }\r
+ first = false;\r
+ th = (sum / nn);\r
+ int g = in_buf[y*size.w+x];\r
+ out_buf[y*size.w+x] = th < g ? 1 : 0;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.qrcode;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_RgbToGs;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.*;\r
+\r
+/**\r
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。\r
+ * \r
+ */\r
+public class NyARSingleQrDetector\r
+{\r
+ private static final int AR_SQUARE_MAX = 100;\r
+\r
+ private boolean _is_continue = false;\r
+ private INyARSquareContourDetector _square_detect;\r
+\r
+ private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
+\r
+ protected INyARTransMat _transmat;\r
+\r
+ private double _marker_width;\r
+\r
+ // 検出結果の保存用\r
+ private NyARSquare _detected_square;\r
+\r
+\r
+ /**\r
+ * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。\r
+ * \r
+ * @param i_param\r
+ * カメラパラメータを指定します。\r
+ * @param i_marker_width\r
+ * ARコードの物理サイズを、ミリメートルで指定します。\r
+ * @throws NyARException\r
+ */\r
+ public NyARSingleQrDetector(NyARParam i_param, double i_marker_width) throws NyARException\r
+ {\r
+ final NyARIntSize scr_size=i_param.getScreenSize(); \r
+ // 解析オブジェクトを作る\r
+ this._square_detect = new NyARQrCodeDetector(i_param.getDistortionFactor(),scr_size);\r
+ this._transmat = new NyARTransMat_ARToolKit(i_param);\r
+ this._marker_width = i_marker_width;\r
+ //2値画像バッファを作る\r
+ this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
+ //中間のグレースケール画像のバッファを作る\r
+ this._gs_raster=new NyARGrayscaleRaster(scr_size.w,scr_size.h);\r
+ }\r
+ private NyARBinRaster _bin_raster;\r
+ private NyARGrayscaleRaster _gs_raster;\r
+ //画処理フィルター\r
+ private INyARRasterFilter_RgbToGs _rgb2gs_filter=new NyARRasterFilter_RgbAve();\r
+ private INyARRasterFilter_GsToBin _gstobin_filter=new NyARRasterFilter_QrAreaAverage();\r
+\r
+ /**\r
+ * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+ * \r
+ * @param i_raster\r
+ * マーカーを検出するイメージを指定します。イメージサイズは、カメラパラメータ\r
+ * と一致していなければなりません。\r
+ * @return マーカーが検出できたかを真偽値で返します。\r
+ * @throws NyARException\r
+ */\r
+ public boolean detectMarkerLite(INyARRgbRaster i_raster,int i_threshold) throws NyARException\r
+ {\r
+ //サイズチェック\r
+ if(!this._bin_raster.getSize().isEqualSize(i_raster.getSize())){\r
+ throw new NyARException();\r
+ }\r
+ //グレースケールに変換\r
+ this._rgb2gs_filter.doFilter(i_raster, this._gs_raster);\r
+ //2値イメージに変換\r
+ this._gstobin_filter.doFilter(this._gs_raster, this._bin_raster); \r
+ \r
+ this._detected_square = null;\r
+ NyARSquareStack l_square_list = this._square_list;\r
+ // スクエアコードを探す\r
+ this._square_detect.detectMarkerCB(this._bin_raster, l_square_list);\r
+ //変換する\r
+\r
+\r
+ int number_of_square = l_square_list.getLength();\r
+ // コードは見つかった?\r
+ if (number_of_square < 1) {\r
+ return false;\r
+ }\r
+ this._detected_square=l_square_list.getItem(0);\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。\r
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。\r
+ * \r
+ * @param o_result\r
+ * 変換行列を受け取るオブジェクトを指定します。\r
+ * @throws NyARException\r
+ */\r
+ public void getTransmationMatrix(NyARTransMatResult o_result) throws NyARException\r
+ {\r
+ // 一番一致したマーカーの位置とかその辺を計算\r
+ if (this._is_continue) {\r
+ this._transmat.transMatContinue(this._detected_square,this._detected_square.direction,this._marker_width, o_result);\r
+ } else {\r
+ this._transmat.transMat(this._detected_square,this._detected_square.direction,this._marker_width, o_result);\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * getTransmationMatrixの計算モードを設定します。 初期値はTRUEです。\r
+ * \r
+ * @param i_is_continue\r
+ * TRUEなら、transMatCont互換の計算をします。 FALSEなら、transMat互換の計算をします。\r
+ */\r
+ public void setContinueMode(boolean i_is_continue)\r
+ {\r
+ this._is_continue = i_is_continue;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JOGL sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.qrcode;\r
+\r
+import java.awt.event.*;\r
+import java.awt.*;\r
+import javax.media.Buffer;\r
+import javax.media.opengl.*;\r
+import com.sun.opengl.util.*;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+/**\r
+ * QRコードをマーカーの代わりに使うサンプルプログラム。\r
+ * 頂点と方位は認識できるけど、QRコードのデコードはしてません。\r
+ * \r
+ */\r
+public class SingleQrSample implements GLEventListener, JmfCaptureListener\r
+{\r
+ private final String CARCODE_FILE = "../../Data/patt.hiro";\r
+\r
+ private final String PARAM_FILE = "../../Data/camera_para.dat";\r
+\r
+ private final static int SCREEN_X = 320;\r
+\r
+ private final static int SCREEN_Y = 240;\r
+\r
+ private Animator _animator;\r
+\r
+ private GLNyARRaster_RGB _cap_image;\r
+\r
+ private JmfCaptureDevice _capture;\r
+\r
+ private GL _gl;\r
+ private NyARGLUtil _glnya;\r
+\r
+ //NyARToolkit関係\r
+ private NyARSingleQrDetector _nya;\r
+ private NyARParam _ar_param;\r
+\r
+ private double[] _camera_projection=new double[16];\r
+ \r
+ /**\r
+ * 立方体を書く\r
+ *\r
+ */\r
+ void drawCube()\r
+ {\r
+ // Colour cube data.\r
+ int polyList = 0;\r
+ float fSize = 0.5f;//マーカーサイズに対して0.5倍なので、4cmの立方体\r
+ int f, i;\r
+ float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };\r
+ float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };\r
+ int cube_num_faces = 6;\r
+ short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };\r
+\r
+ if (polyList == 0) {\r
+ polyList = _gl.glGenLists(1);\r
+ _gl.glNewList(polyList, GL.GL_COMPILE);\r
+ _gl.glBegin(GL.GL_QUADS);\r
+ for (f = 0; f < cube_num_faces; f++)\r
+ for (i = 0; i < 4; i++) {\r
+ _gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);\r
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ }\r
+ _gl.glEnd();\r
+ _gl.glColor3f(0.0f, 0.0f, 0.0f);\r
+ for (f = 0; f < cube_num_faces; f++) {\r
+ _gl.glBegin(GL.GL_LINE_LOOP);\r
+ for (i = 0; i < 4; i++)\r
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ _gl.glEnd();\r
+ }\r
+ _gl.glEndList();\r
+ }\r
+\r
+ _gl.glPushMatrix(); // Save world coordinate system.\r
+ _gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.\r
+ _gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.\r
+ _gl.glDisable(GL.GL_LIGHTING); // Just use colours.\r
+ _gl.glCallList(polyList); // Draw the cube.\r
+ _gl.glPopMatrix(); // Restore world coordinate system.\r
+\r
+ }\r
+\r
+ public SingleQrSample()\r
+ {\r
+ Frame frame = new Frame("SingleQrSample");\r
+\r
+ // 3Dを描画するコンポーネント\r
+ GLCanvas canvas = new GLCanvas();\r
+ frame.add(canvas);\r
+ canvas.addGLEventListener(this);\r
+ frame.addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+\r
+ frame.setVisible(true);\r
+ Insets ins = frame.getInsets();\r
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
+ }\r
+\r
+ public void init(GLAutoDrawable drawable)\r
+ {\r
+ _gl = drawable.getGL();\r
+ _gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+ //NyARToolkitの準備\r
+ try {\r
+ //キャプチャの準備\r
+ JmfCaptureDeviceList list=new JmfCaptureDeviceList();\r
+ _capture=list.getDevice(0);\r
+ _capture.setCaptureFormat(SCREEN_X, SCREEN_Y, 15f);\r
+ _capture.setOnCapture(this);\r
+ \r
+ //NyARToolkitの準備\r
+ _ar_param = new NyARParam();\r
+ NyARCode ar_code = new NyARCode(16, 16);\r
+ _ar_param.loadARParamFromFile(PARAM_FILE);\r
+ _ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);\r
+ _nya = new NyARSingleQrDetector(_ar_param,80);\r
+ _nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。\r
+ ar_code.loadARPattFromFile(CARCODE_FILE);\r
+ //NyARToolkit用の支援クラス\r
+ _glnya = new NyARGLUtil(_gl);\r
+ //GL対応のRGBラスタオブジェクト\r
+ _cap_image = new GLNyARRaster_RGB(_ar_param,_capture.getCaptureFormat());\r
+ //キャプチャ開始\r
+ _capture.start();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ //カメラパラメータの計算\r
+ _glnya.toCameraFrustumRH(_ar_param,_camera_projection);\r
+\r
+ _animator = new Animator(drawable);\r
+ _animator.start();\r
+ return;\r
+ }\r
+\r
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
+ {\r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
+ _gl.glViewport(0, 0, width, height);\r
+\r
+ //視体積の設定\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadIdentity();\r
+ //見る位置\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ _gl.glLoadIdentity();\r
+ }\r
+ private NyARTransMatResult __display_transmat_result=new NyARTransMatResult();\r
+ private double[] __display_wk=new double[16];\r
+ \r
+ public void display(GLAutoDrawable drawable)\r
+ {\r
+ NyARTransMatResult transmat_result=__display_transmat_result;\r
+ try {\r
+ if (!_cap_image.hasData()) {\r
+ return;\r
+ }\r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame. \r
+ //画像チェックしてマーカー探して、背景を書く\r
+ boolean is_marker_exist;\r
+ synchronized (_cap_image) {\r
+ is_marker_exist = _nya.detectMarkerLite(_cap_image, 0);\r
+ //背景を書く\r
+ _glnya.drawBackGround(_cap_image, 1.0);\r
+ }\r
+ //マーカーがあれば、立方体を描画\r
+ if (is_marker_exist) {\r
+ //マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。\r
+ // Projection transformation.\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadMatrixd(_camera_projection, 0);\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ // Viewing transformation.\r
+ _gl.glLoadIdentity();\r
+ //変換行列を取得\r
+ _nya.getTransmationMatrix(transmat_result);\r
+ //変換行列をOpenGL形式に変換\r
+ _glnya.toCameraViewRH(transmat_result, __display_wk);\r
+ _gl.glLoadMatrixd(__display_wk, 0);\r
+\r
+ // All other lighting and geometry goes here.\r
+ drawCube();\r
+ }\r
+ Thread.sleep(1);//タスク実行権限を一旦渡す\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+ synchronized (_cap_image) {\r
+ _cap_image.setBuffer(i_buffer);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
+ {\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ new SingleQrSample();\r
+ }\r
+}\r
--- /dev/null
+/* このソースは実験用のソースです。
+ * 動いたり動かなかったりします。
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.qrcode;
+
+import javax.media.*;
+
+import javax.media.util.BufferToImage;
+import javax.media.format.*;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
+import jp.nyatla.nyartoolkit.utils.j2se.LabelingBufferdImage;
+
+
+import java.awt.*;
+
+import jp.nyatla.nyartoolkit.core.analyzer.raster.threshold.INyARRasterThresholdAnalyzer;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabeling_ARToolKit;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.rasteranalyzer.threshold.NyARRasterThresholdAnalyzer_DiffHistgram;
+import jp.nyatla.nyartoolkit.core.rasterfilter.*;
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_RgbToGs;
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.gs2bin.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold.*;
+
+
+
+public class SingleQrTest extends Frame implements JmfCaptureListener
+{
+ private final String camera_file = "../../Data/camera_para.dat";
+
+ private JmfNyARRaster_RGB _raster;
+
+ private JmfCaptureDevice capture;
+ private NyARParam ap;
+ public SingleQrTest() throws NyARException, NyARException
+ {
+ setBounds(0, 0, 640 + 64, 720 + 64);
+ // キャプチャの準備
+ JmfCaptureDeviceList list=new JmfCaptureDeviceList();
+ capture=list.getDevice(0);
+ capture.setCaptureFormat(320,240,30.0f);
+ capture.setOnCapture(this);
+
+ // キャプチャイメージ用のラスタを準備
+ this._raster = new JmfNyARRaster_RGB(320, 240,capture.getCaptureFormat());
+
+ // AR用カメラパラメタファイルをロード
+ ap = new NyARParam();
+ ap.loadARParamFromFile(camera_file);
+ ap.changeScreenSize(320, 240);
+
+
+ }
+
+ private NyARBinRaster _binraster1 = new NyARBinRaster(320, 240);
+
+ private NyARGrayscaleRaster _gsraster1 = new NyARGrayscaleRaster(320, 240);
+ private INyARRasterThresholdAnalyzer _tha=new NyARRasterThresholdAnalyzer_DiffHistgram();
+
+ private LabelingBufferdImage _bimg = new LabelingBufferdImage(320, 240);
+
+
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+
+ try {
+ // キャプチャしたバッファをラスタにセット
+ _raster.setBuffer(i_buffer);
+
+ Graphics g = getGraphics();
+ // キャプチャ画像
+ BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+ Image img = b2i.createImage(i_buffer);
+ this.getGraphics().drawImage(img, 32, 32, this);
+
+ // 画像1
+ INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbAve();
+// INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbMul();
+
+ filter_rgb2gs.doFilter(_raster, _gsraster1);
+ this._bimg.drawImage(this._gsraster1);
+ this.getGraphics().drawImage(this._bimg, 32 + 320, 32, 320 + 320 + 32, 240 + 32, 0, 240, 320, 0, this);
+ _tha.analyzeRaster(_gsraster1);
+ NyARRasterFilter_Threshold gs2bin=new NyARRasterFilter_Threshold(_tha.getThreshold());
+
+
+ // 画像2
+ gs2bin.doFilter(_gsraster1, _binraster1);
+ this._bimg.drawImage(_binraster1);
+ this.getGraphics().drawImage(this._bimg, 32, 32 + 240, 320 + 32, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+ // 画像3
+ NyARLabelingImage limage = new NyARLabelingImage(320, 240);
+ NyARLabeling_ARToolKit labeling = new NyARLabeling_ARToolKit();
+ labeling.labeling(_binraster1,limage);
+ this._bimg.drawImage(this._gsraster1);
+
+ NyARSquareStack stack = new NyARSquareStack(100);
+ NyARQrCodeDetector detect = new NyARQrCodeDetector(ap.getDistortionFactor(), new NyARIntSize(320,240));
+// detect.bimg=this._bimg;
+
+ detect.detectMarker(_binraster1, stack);
+ for (int i = 0; i < stack.getLength(); i++) {
+ NyARSquare[] square_ptr = stack.getArray();
+ int d=square_ptr[i].direction;
+ int[] xp=new int[4];
+ int[] yp=new int[4];
+ for(int i2=0;i2<4;i2++){
+ xp[i2]=square_ptr[i].imvertex[(i2+d)%4].x;
+ yp[i2]=square_ptr[i].imvertex[(i2+d)%4].y;
+ }
+ Graphics g2=this._bimg.getGraphics();
+ g2.setColor(Color.RED);
+ g2.drawPolygon(xp, yp,3);
+ g2.setColor(Color.CYAN);
+ g2.drawRect(square_ptr[i].imvertex[d].x, square_ptr[i].imvertex[d].y,5,5);
+ }
+ this.getGraphics().drawImage(this._bimg, 32 + 320, 32 + 240, 320 + 32 + 320, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+ // 画像3
+ // threshold.debugDrawHistgramMap(_workraster, _workraster2);
+ // this._bimg2.setImage(this._workraster2);
+ // this.getGraphics().drawImage(this._bimg2, 32+320, 32+240,320+32+320,240+32+240,0,240,320,0, this);
+
+ // 画像4
+ // NyARRasterThresholdAnalyzer_SlidePTile threshold=new NyARRasterThresholdAnalyzer_SlidePTile(15);
+ // threshold.analyzeRaster(_gsraster1);
+ // filter_gs2bin=new NyARRasterFilter_AreaAverage();
+ // filter_gs2bin.doFilter(_gsraster1, _binraster1);
+ // this._bimg.drawImage(_binraster1);
+
+ // NyARRasterDetector_QrCodeEdge detector=new NyARRasterDetector_QrCodeEdge(10000);
+ // detector.analyzeRaster(_binraster1);
+
+ // this._bimg.overlayData(detector.geResult());
+
+ // this.getGraphics().drawImage(this._bimg, 32, 32+480,320+32,480+32+240,0,240,320,0, this);
+ // 画像5
+
+ /*
+ * threshold2.debugDrawHistgramMap(_workraster, _workraster2); this._bimg2.drawImage(this._workraster2); this.getGraphics().drawImage(this._bimg2,
+ * 32+320, 32+480,320+32+320,480+32+240,0,240,320,0, this);
+ */
+
+ // this.getGraphics().drawImage(this._bimg, 32, 32, this);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void startCapture()
+ {
+ try {
+ capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ SingleQrTest mainwin = new SingleQrTest();
+ mainwin.setVisible(true);
+ mainwin.startCapture();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JOGL sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.quadx2;\r
+\r
+import java.awt.event.WindowAdapter;\r
+import java.awt.event.WindowEvent;\r
+import java.awt.*;\r
+\r
+import javax.media.Buffer;\r
+\r
+import javax.media.opengl.GL;\r
+import javax.media.opengl.GLAutoDrawable;\r
+import javax.media.opengl.GLEventListener;\r
+import javax.media.opengl.GLCanvas;\r
+\r
+import com.sun.opengl.util.Animator;\r
+\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+/**\r
+ * simpleLiteと同じようなテストプログラム\r
+ * 出来る限りARToolKitのサンプルと似せて作ってあります。\r
+ * 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。\r
+ * \r
+ */\r
+public class JavaSimpleLite_Quad implements GLEventListener, JmfCaptureListener\r
+{\r
+ private final String CARCODE_FILE = "../../Data/patt.hiro";\r
+\r
+ private final String PARAM_FILE = "../../Data/camera_para.dat";\r
+\r
+ private final static int SCREEN_X = 320;\r
+\r
+ private final static int SCREEN_Y = 240;\r
+\r
+ private Animator _animator;\r
+\r
+ private GLNyARRaster_RGB _cap_image;\r
+\r
+ private JmfCaptureDevice _capture;\r
+\r
+ private GL _gl;\r
+\r
+ private NyARGLUtil _glnya;\r
+\r
+ //NyARToolkit関係\r
+ private NyARSingleDetectMarker_Quad _nya;\r
+\r
+ private NyARParam _ar_param;\r
+\r
+ /**\r
+ * 立方体を書く\r
+ *\r
+ */\r
+ void drawCube()\r
+ {\r
+ // Colour cube data.\r
+ int polyList = 0;\r
+ float fSize = 0.5f;//マーカーサイズに対して0.5倍なので、4cmの立方体\r
+ int f, i;\r
+ float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };\r
+ float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };\r
+ int cube_num_faces = 6;\r
+ short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };\r
+\r
+ if (polyList == 0) {\r
+ polyList = _gl.glGenLists(1);\r
+ _gl.glNewList(polyList, GL.GL_COMPILE);\r
+ _gl.glBegin(GL.GL_QUADS);\r
+ for (f = 0; f < cube_num_faces; f++)\r
+ for (i = 0; i < 4; i++) {\r
+ _gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);\r
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ }\r
+ _gl.glEnd();\r
+ _gl.glColor3f(0.0f, 0.0f, 0.0f);\r
+ for (f = 0; f < cube_num_faces; f++) {\r
+ _gl.glBegin(GL.GL_LINE_LOOP);\r
+ for (i = 0; i < 4; i++)\r
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ _gl.glEnd();\r
+ }\r
+ _gl.glEndList();\r
+ }\r
+\r
+ _gl.glPushMatrix(); // Save world coordinate system.\r
+ _gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.\r
+ _gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.\r
+ _gl.glDisable(GL.GL_LIGHTING); // Just use colours.\r
+ _gl.glCallList(polyList); // Draw the cube.\r
+ _gl.glPopMatrix(); // Restore world coordinate system.\r
+\r
+ }\r
+\r
+ public JavaSimpleLite_Quad()\r
+ {\r
+ Frame frame = new Frame("Java simpleLite with NyARToolkit");\r
+\r
+ // 3Dを描画するコンポーネント\r
+ GLCanvas canvas = new GLCanvas();\r
+ frame.add(canvas);\r
+ canvas.addGLEventListener(this);\r
+ frame.addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+\r
+ frame.setVisible(true);\r
+ Insets ins = frame.getInsets();\r
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
+ }\r
+\r
+ public void init(GLAutoDrawable drawable)\r
+ {\r
+ _gl = drawable.getGL();\r
+ _gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+ //NyARToolkitの準備\r
+ try {\r
+ //キャプチャの準備\r
+ JmfCaptureDeviceList list=new JmfCaptureDeviceList();\r
+ _capture=list.getDevice(0);\r
+ _capture.setCaptureFormat(SCREEN_X, SCREEN_Y, 15f);\r
+ _capture.setOnCapture(this);\r
+ //NyARToolkitの準備\r
+ _ar_param = new NyARParam();\r
+ NyARCode ar_code = new NyARCode(16, 16);\r
+ _ar_param.loadARParamFromFile(PARAM_FILE);\r
+ _ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);\r
+ _nya = new NyARSingleDetectMarker_Quad(_ar_param, ar_code, 80.0);\r
+ _nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。\r
+ ar_code.loadARPattFromFile(CARCODE_FILE);\r
+ //NyARToolkit用の支援クラス\r
+ _glnya = new NyARGLUtil(_gl);\r
+ //GL対応のRGBラスタオブジェクト\r
+ _cap_image = new GLNyARRaster_RGB(_ar_param,_capture.getCaptureFormat());\r
+ //キャプチャ開始\r
+ _capture.start();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ //カメラパラメータの計算\r
+ _glnya.toCameraFrustumRH(_ar_param,_camera_projection);\r
+ _animator = new Animator(drawable);\r
+\r
+ _animator.start();\r
+\r
+ }\r
+\r
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
+ {\r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
+ _gl.glViewport(0, 0, width, height);\r
+\r
+ //視体積の設定\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadIdentity();\r
+ //見る位置\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ _gl.glLoadIdentity();\r
+ }\r
+ private double[] _camera_projection=new double[16];\r
+ private NyARTransMatResult __display_transmat_result=new NyARTransMatResult();\r
+ private double[] __display_wk=new double[16];\r
+ public void display(GLAutoDrawable drawable)\r
+ {\r
+ NyARTransMatResult transmat_result=__display_transmat_result;\r
+ try {\r
+ if (!_cap_image.hasData()) {\r
+ return;\r
+ }\r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame. \r
+ //画像チェックしてマーカー探して、背景を書く\r
+ boolean is_marker_exist;\r
+ synchronized (_cap_image) {\r
+ is_marker_exist = _nya.detectMarkerLite(_cap_image, 110);\r
+ //背景を書く\r
+ _glnya.drawBackGround(_cap_image, 1.0);\r
+ }\r
+ //マーカーがあれば、立方体を描画\r
+ if (is_marker_exist) {\r
+ //マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。\r
+ // Projection transformation.\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadMatrixd(_camera_projection, 0);\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ // Viewing transformation.\r
+ _gl.glLoadIdentity();\r
+ //変換行列を取得\r
+ _nya.getTransmationMatrix(transmat_result);\r
+ //変換行列をOpenGL形式に変換\r
+ _glnya.toCameraViewRH(transmat_result, __display_wk);\r
+ _gl.glLoadMatrixd(__display_wk, 0);\r
+\r
+ // All other lighting and geometry goes here.\r
+ drawCube();\r
+ }\r
+ Thread.sleep(1);//タスク実行権限を一旦渡す\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+ synchronized (_cap_image) {\r
+ _cap_image.setBuffer(i_buffer);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
+ {\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ new JavaSimpleLite_Quad();\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.quadx2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*;\r
+\r
+/**\r
+ * 1/4のサイズの画像に変換しながら閾値判定する関数\r
+ * \r
+ */\r
+public class NyARRasterFilter_ARTTh_Quad implements INyARRasterFilter_Bin\r
+{\r
+ private int _threshold;\r
+\r
+ public NyARRasterFilter_ARTTh_Quad(int i_threshold)\r
+ {\r
+ this._threshold = i_threshold;\r
+ }\r
+ public void setThreshold(int i_threshold)\r
+ {\r
+ this._threshold = i_threshold;\r
+ }\r
+\r
+ public void doFilter(INyARRgbRaster i_input, NyARBinRaster i_output) throws NyARException\r
+ {\r
+ INyARBufferReader in_buffer_reader=i_input.getBufferReader(); \r
+ INyARBufferReader out_buffer_reader=i_output.getBufferReader();\r
+ int in_buf_type=in_buffer_reader.getBufferType();\r
+\r
+ NyARIntSize size = i_output.getSize();\r
+ assert (out_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8));\r
+ assert (checkInputType(in_buf_type)==true); \r
+ assert (i_input.getSize().isEqualSize(size.w*2,size.h*2) == true);\r
+\r
+ int[] out_buf = (int[]) out_buffer_reader.getBuffer();\r
+ byte[] in_buf = (byte[]) in_buffer_reader.getBuffer();\r
+\r
+ switch (in_buffer_reader.getBufferType()) {\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ convert24BitRgb(in_buf, out_buf, size);\r
+ break;\r
+// case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32:\r
+// convert32BitRgbx(in_buf, out_buf, size);\r
+// break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ return;\r
+ }\r
+\r
+ private void convert24BitRgb(byte[] i_in, int[] i_out, NyARIntSize i_size)\r
+ {\r
+ final int size_w=i_size.w*2;\r
+ final int x_mod_end= size_w-(size_w%8);\r
+ final int th=this._threshold*3;\r
+ int bp =(size_w*i_size.h*2-1)*3; \r
+ int w;\r
+ int x; \r
+ for (int y =i_size.h-1; y>=0 ; y--){\r
+ //端数分\r
+ final int row_ptr=y*i_size.w;\r
+ for (x = i_size.w-1;x>=x_mod_end;x--) {\r
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x]=w<=th?0:1;\r
+ bp -= 6;\r
+ }\r
+ //タイリング \r
+ for (;x>=0;x-=8) {\r
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x]=w<=th?0:1;\r
+ bp -= 6;\r
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-1]=w<=th?0:1;\r
+ bp -= 6;\r
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-2]=w<=th?0:1;\r
+ bp -= 6;\r
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-3]=w<=th?0:1;\r
+ bp -= 6;\r
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-4]=w<=th?0:1;\r
+ bp -= 6;\r
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-5]=w<=th?0:1;\r
+ bp -= 6;\r
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-6]=w<=th?0:1;\r
+ bp -= 6;\r
+ w=((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-7]=w<=th?0:1;\r
+ bp -= 6;\r
+ }\r
+ //1行飛ばし\r
+ bp-=size_w*3;\r
+ }\r
+ return;\r
+ }\r
+ private void convert32BitRgbx(byte[] i_in, int[] i_out, NyARIntSize i_size)\r
+ {\r
+ final int size_w=i_size.w;\r
+ final int x_mod_end= size_w-(size_w%8);\r
+ final int th=this._threshold*3;\r
+ int bp =(size_w*i_size.h-1)*4;\r
+ int w;\r
+ int x;\r
+ for (int y =i_size.h-1; y>=0 ; y--){\r
+ final int row_ptr=y*i_size.w;\r
+\r
+ //端数分\r
+ for (x = size_w-1;x>=x_mod_end;x--) {\r
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x]=w<=th?0:1;\r
+ bp -= 4;\r
+ }\r
+ //タイリング\r
+ for (;x>=0;x-=8) {\r
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x]=w<=th?0:1;\r
+ bp -= 4;\r
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-1]=w<=th?0:1;\r
+ bp -= 4;\r
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-2]=w<=th?0:1;\r
+ bp -= 4;\r
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-3]=w<=th?0:1;\r
+ bp -= 4;\r
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-4]=w<=th?0:1;\r
+ bp -= 4;\r
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-5]=w<=th?0:1;\r
+ bp -= 4;\r
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-6]=w<=th?0:1;\r
+ bp -= 4;\r
+ w= ((i_in[bp] & 0xff) + (i_in[bp + 1] & 0xff) + (i_in[bp + 2] & 0xff));\r
+ i_out[row_ptr+x-7]=w<=th?0:1;\r
+ bp -= 4;\r
+ } \r
+ }\r
+ return;\r
+ }\r
+ \r
+ private boolean checkInputType(int i_input_type) throws NyARException\r
+ {\r
+ switch(i_input_type){\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+// case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32:\r
+// case INyARBufferReader.BUFFERFORMAT_BYTE1D_R5G6B5_16LE:\r
+ return true;\r
+ default:\r
+ return false;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.quadx2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+import jp.nyatla.nyartoolkit.sandbox.x2.NyARTransMat_X2;\r
+\r
+\r
+/**\r
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。\r
+ * \r
+ */\r
+public class NyARSingleDetectMarker_Quad\r
+{\r
+ private static final int AR_SQUARE_MAX = 100;\r
+\r
+ private boolean _is_continue = false;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;\r
+ private INyARSquareContourDetector _square_detect;\r
+\r
+ private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
+\r
+ protected INyARTransMat _transmat;\r
+\r
+ private double _marker_width;\r
+\r
+ // 検出結果の保存用\r
+ private int _detected_direction;\r
+\r
+ private double _detected_confidence;\r
+\r
+ private NyARSquare _detected_square;\r
+\r
+ private INyARColorPatt _patt;\r
+\r
+ /**\r
+ * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。\r
+ * \r
+ * @param i_param\r
+ * カメラパラメータを指定します。\r
+ * @param i_code\r
+ * 検出するARCodeを指定します。\r
+ * @param i_marker_width\r
+ * ARコードの物理サイズを、ミリメートルで指定します。\r
+ * @throws NyARException\r
+ */\r
+ public NyARSingleDetectMarker_Quad(NyARParam i_param, NyARCode i_code, double i_marker_width) throws NyARException\r
+ {\r
+ final NyARIntSize scr_size=i_param.getScreenSize(); \r
+ // 解析オブジェクトを作る\r
+ this._square_detect = new NyARSquareDetector_Quad(i_param.getDistortionFactor(),scr_size);\r
+ this._transmat = new NyARTransMat_X2(i_param);\r
+ // 比較コードを保存\r
+ this._marker_width = i_marker_width;\r
+ // 評価パターンのホルダを作る\r
+ this._patt = new NyARColorPatt_O3(i_code.getWidth(), i_code.getHeight());\r
+ // i_codeに対応する評価器を作る。\r
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA(i_code);\r
+ //2値画像バッファを作る\r
+ this._bin_raster=new NyARBinRaster(scr_size.w/2,scr_size.h/2);\r
+ //差分データインスタンスの作成\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(i_code.getWidth(), i_code.getHeight());\r
+ \r
+ return;\r
+ }\r
+\r
+ private NyARBinRaster _bin_raster;\r
+// private NyARRasterFilter_ARToolkitThreshold _tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100);\r
+ private NyARRasterFilter_ARTTh_Quad _tobin_filter=new NyARRasterFilter_ARTTh_Quad(100);\r
+\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+\r
+ /**\r
+ * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+ * \r
+ * @param i_raster\r
+ * マーカーを検出するイメージを指定します。イメージサイズは、カメラパラメータ\r
+ * と一致していなければなりません。\r
+ * @return マーカーが検出できたかを真偽値で返します。\r
+ * @throws NyARException\r
+ */\r
+ public boolean detectMarkerLite(INyARRgbRaster i_raster,int i_threshold) throws NyARException\r
+ {\r
+ //サイズチェック\r
+ if(!this._bin_raster.getSize().isEqualSize(i_raster.getSize().w/2,i_raster.getSize().h/2)){\r
+ throw new NyARException();\r
+ }\r
+\r
+ //ラスタを(1/4の画像の)2値イメージに変換する.\r
+ this._tobin_filter.setThreshold(i_threshold);\r
+ this._tobin_filter.doFilter(i_raster,this._bin_raster);\r
+ \r
+ \r
+ this._detected_square = null;\r
+ NyARSquareStack l_square_list = this._square_list;\r
+ // スクエアコードを探す\r
+ this._square_detect.detectMarkerCB(this._bin_raster, l_square_list);\r
+\r
+\r
+ int number_of_square = l_square_list.getLength();\r
+ // コードは見つかった?\r
+ if (number_of_square < 1) {\r
+ return false;\r
+ }\r
+\r
+ boolean result=false;\r
+ NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+ int square_index = 0;\r
+ int direction = NyARSquare.DIRECTION_UNKNOWN;\r
+ double confidence = 0;\r
+ for(int i=0;i<number_of_square;i++){\r
+ // 評価基準になるパターンをイメージから切り出す\r
+ if (!this._patt.pickFromRaster(i_raster,l_square_list.getItem(i).imvertex)){\r
+ continue;\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._patt);\r
+ this._match_patt.evaluate(this._deviation_data,mr);\r
+\r
+ final double c2 = mr.confidence;\r
+ if (confidence > c2) {\r
+ continue;\r
+ }\r
+ // もっと一致するマーカーがあったぽい\r
+ square_index = i;\r
+ direction = mr.direction;\r
+ confidence = c2;\r
+ result=true;\r
+ }\r
+ \r
+ // マーカー情報を保存\r
+ this._detected_square = (NyARSquare)l_square_list.getItem(square_index);\r
+ this._detected_direction = direction;\r
+ this._detected_confidence = confidence;\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。\r
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。\r
+ * \r
+ * @param o_result\r
+ * 変換行列を受け取るオブジェクトを指定します。\r
+ * @throws NyARException\r
+ */\r
+ public void getTransmationMatrix(NyARTransMatResult o_result) throws NyARException\r
+ {\r
+ // 一番一致したマーカーの位置とかその辺を計算\r
+ if (this._is_continue) {\r
+ this._transmat.transMatContinue(this._detected_square,this._detected_direction,this._marker_width, o_result);\r
+ } else {\r
+ this._transmat.transMat(this._detected_square,this._detected_direction,this._marker_width, o_result);\r
+ }\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 検出したマーカーの一致度を返します。\r
+ * \r
+ * @return マーカーの一致度を返します。0~1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。\r
+ * @throws NyARException\r
+ */\r
+ public double getConfidence()\r
+ {\r
+ return this._detected_confidence;\r
+ }\r
+\r
+ /**\r
+ * 検出したマーカーの方位を返します。\r
+ * \r
+ * @return 0,1,2,3の何れかを返します。\r
+ */\r
+ public int getDirection()\r
+ {\r
+ return this._detected_direction;\r
+ }\r
+\r
+ /**\r
+ * getTransmationMatrixの計算モードを設定します。 初期値はTRUEです。\r
+ * \r
+ * @param i_is_continue\r
+ * TRUEなら、transMatCont互換の計算をします。 FALSEなら、transMat互換の計算をします。\r
+ */\r
+ public void setContinueMode(boolean i_is_continue)\r
+ {\r
+ this._is_continue = i_is_continue;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.quadx2;\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.*;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.ContourPickup;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.Coord2Linear;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+\r
+import jp.nyatla.nyartoolkit.sandbox.x2.*;\r
+\r
+\r
+/**\r
+ * 1/4に解像度を落して解析するNyARSquareDetector_X2\r
+ * 与えるBinRasterが既に1/4のサイズになっていないといけないことに注意\r
+ */\r
+public class NyARSquareDetector_Quad implements INyARSquareContourDetector\r
+{\r
+ private static int AR_AREA_MAX = 25000;// #define AR_AREA_MAX 100000\r
+\r
+ private static int AR_AREA_MIN = 20;// #define AR_AREA_MIN 70\r
+ private int _width;\r
+ private int _height;\r
+\r
+ private NyARLabeling_ARToolKit _labeling;\r
+\r
+ private NyARLabelingImage _limage;\r
+\r
+ private final LabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new LabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
+ private final Coord2Linear _sqconvertor;\r
+ private final ContourPickup _cpickup=new ContourPickup();\r
+ /**\r
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARSquareDetector_Quad(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException\r
+ {\r
+ this._width = i_size.w / 2;\r
+ this._height = i_size.h / 2;\r
+ this._labeling = new NyARLabeling_ARToolKit();\r
+ this._limage = new NyARLabelingImage(this._width, this._height);\r
+ this._sqconvertor=new Coord2Linear(i_size,i_dist_factor_ref); \r
+\r
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
+ int number_of_coord = (this._width + this._height) * 2;\r
+\r
+ // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
+ this._max_coord = number_of_coord;\r
+ this._xcoord = new int[number_of_coord * 2];\r
+ this._ycoord = new int[number_of_coord * 2];\r
+\r
+ //1/4サイズの歪みマップを作る\r
+ NyARCameraDistortionFactor quadfactor = new NyARCameraDistortionFactor();\r
+ quadfactor.copyFrom(i_dist_factor_ref);\r
+ quadfactor.changeScale(0.5);\r
+ }\r
+\r
+ private int _max_coord;\r
+ private int[] _xcoord;\r
+ private int[] _ycoord;\r
+\r
+ /**\r
+ * arDetectMarker2を基にした関数\r
+ * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。\r
+ * directionの確定は行いません。\r
+ * @param i_raster\r
+ * 解析する2値ラスタイメージを指定します。\r
+ * @param o_square_stack\r
+ * 抽出した正方形候補を格納するリスト\r
+ * @throws NyARException\r
+ */\r
+ public void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
+ {\r
+ NyARLabelingImage limage = this._limage;\r
+\r
+ // 初期化\r
+\r
+ // マーカーホルダをリセット\r
+ o_square_stack.clear();\r
+\r
+ // ラベリング\r
+ this._labeling.labeling(i_raster,limage);\r
+\r
+ // ラベル数が0ならここまで\r
+ int label_num = limage.getLabelStack().getLength();\r
+ if (label_num < 1)\r
+ {\r
+ return;\r
+ }\r
+\r
+ NyARLabelingLabelStack stack = limage.getLabelStack();\r
+ // ラベルを大きい順に整列\r
+ stack.sortByArea();\r
+ \r
+ NyARLabelingLabel[] labels = stack.getArray();\r
+\r
+ // デカいラベルを読み飛ばし\r
+ int i;\r
+ for (i = 0; i < label_num; i++)\r
+ {\r
+ // 検査対象内のラベルサイズになるまで無視\r
+ if (labels[i].area <= AR_AREA_MAX)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ int xsize = this._width;\r
+ int ysize = this._height;\r
+ int[] xcoord = this._xcoord;\r
+ int[] ycoord = this._ycoord;\r
+ int coord_max = this._max_coord;\r
+ final LabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
+\r
+ int label_area;\r
+ NyARLabelingLabel label_pt;\r
+\r
+ //重なりチェッカの最大数を設定\r
+ overlap.setMaxLabels(label_num);\r
+\r
+ for (; i < label_num; i++)\r
+ {\r
+ label_pt = labels[i];\r
+ label_area = label_pt.area;\r
+ // 検査対象サイズよりも小さくなったら終了\r
+ if (label_area < AR_AREA_MIN)\r
+ {\r
+ break;\r
+ }\r
+ // クリップ領域が画面の枠に接していれば除外\r
+ if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2)\r
+ {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){\r
+ continue;\r
+ }\r
+ if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2)\r
+ {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){\r
+ continue;\r
+ }\r
+ // 既に検出された矩形との重なりを確認\r
+ if (!overlap.check(label_pt))\r
+ {\r
+ // 重なっているようだ。\r
+ continue;\r
+ }\r
+ // 既に検出された矩形との重なりを確認\r
+ if (!overlap.check(label_pt)) {\r
+ // 重なっているようだ。\r
+ continue;\r
+ }\r
+ // 輪郭を取得\r
+ final int coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
+ if (coord_num == coord_max) {\r
+ // 輪郭が大きすぎる。\r
+ continue;\r
+ }\r
+ //輪郭分析用に正規化する。\r
+ final int vertex1 = Coord2Linear.normalizeCoord(xcoord, ycoord, coord_num);\r
+\r
+ //ここから先が輪郭分析\r
+ NyARSquare square_ptr = o_square_stack.prePush();\r
+ if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
+ o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
+ continue; \r
+ }\r
+ \r
+ // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
+ overlap.push(label_pt);\r
+ }\r
+ return;\r
+ }\r
+}\r
+\r
+\r
--- /dev/null
+package jp.nyatla.nyartoolkit.sandbox.utils;\r
+\r
+/**\r
+ * 1区間にある1個のエッジ位置を推定するクラスです。\r
+ *\r
+ */\r
+public class NyARSingleEdgeFinder\r
+{\r
+ public static class TEdgeInfo\r
+ {\r
+ double point; //検出したエッジの位置\r
+ int sub; //エッジの差分\r
+ } \r
+ private int[] _work;\r
+ private int _width;\r
+ private int _height;\r
+ public NyARSingleEdgeFinder(int i_width,int i_height)\r
+ {\r
+ this._work=new int[(i_width>i_height?i_width:i_height)+1];\r
+ this._work[this._work.length-1]=0;\r
+ this._width=i_width;\r
+ this._height=i_height;\r
+ return;\r
+ }\r
+ /**\r
+ * この関数は、一区間に1個のエッジが含まれていると仮定して、その位置を推定します。\r
+ * [n]個の配列を与えた場合、[n+2]~[n-1]の間にあるエッジを検出します。\r
+ * 検出方向は左→右の順です\r
+ * @param i_pixcel\r
+ * @param i_start\r
+ * @param i_length\r
+ * @param o_out\r
+ * @return\r
+ */\r
+ public boolean scanSingleEdgeLeftToRight(int[] i_pixcel,int i_y,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int length=this._width-1;\r
+ int p=i_y*this._width;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p+1]-i_pixcel[p];\r
+ p++;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ }\r
+ /**\r
+ * 線分内のエッジを検出します。\r
+ * この関数は、1区間に1個のエッジが含まれていると仮定して、その位置を推定します。\r
+ * [n]個の配列を与えた場合、[n+2]~[n-1]の間にあるエッジを検出します。\r
+ * 検出方向は右→左の順です\r
+ * @param i_pixcel\r
+ * @param i_start\r
+ * @param i_length\r
+ * @param o_out\r
+ * @return\r
+ */\r
+ public boolean scanSingleEdgeRightToLeft(int[] i_pixcel,int i_y,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int length=this._width-1;\r
+ int p=(i_y+1)*this._width-1;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p-1]-i_pixcel[p];\r
+ p--;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ } \r
+ public boolean scanSingleEdgeTopToBottom(int[] i_pixcel,int i_x,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int step=this._width;\r
+ final int length=this._height-1;\r
+ int p=i_x;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p+step]-i_pixcel[p];\r
+ p+=step;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ }\r
+ public boolean scanSingleEdgeBottomToTop(int[] i_pixcel,int i_x,TEdgeInfo o_out)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int step=this._width;\r
+ final int length=this._height-1;\r
+ int p=i_x+step*length;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixcel[p-step]-i_pixcel[p];\r
+ p-=step;\r
+ }\r
+ return scanSingleEdge(temp,length,o_out);\r
+ } \r
+ private boolean scanSingleEdge(int[] i_pixels,int i_length,TEdgeInfo o_out)\r
+ {\r
+ //微分(2回目)して、極値2か所を得る\r
+ int max_index,min_index;\r
+ int length=i_length-1;\r
+ max_index=min_index=0;\r
+ int max_value,min_value;\r
+ max_value=min_value=0;\r
+ for(int i2=0;i2<length;i2++){\r
+ int t=i_pixels[i2+1]-i_pixels[i2];\r
+ if(t>max_value){\r
+ max_index=i2;\r
+ max_value=t;\r
+ }\r
+ if(t<min_value){\r
+ min_index=i2;\r
+ min_value=t;\r
+ }\r
+ }\r
+ //同符号である場合、範囲内にエッジはない\r
+ if(max_value*min_value>=0){\r
+ return false;\r
+ } \r
+ o_out.point=(max_index+min_index)/2.0;\r
+ o_out.sub=max_value-min_value;\r
+ return true;\r
+ }\r
+ public int scanEdgeLeftToRight(int[] i_pixel,int i_y,int i_noise_th,double[] o_edge_index)\r
+ {\r
+ final int[] temp=this._work;\r
+ //1回微分(0-8)\r
+ final int length=this._width-1;\r
+ int p=i_y*this._width;\r
+ for(int i2=0;i2<length;i2++){\r
+ temp[i2]=i_pixel[p+1]-i_pixel[p];\r
+ p++;\r
+ }\r
+ //0終端させるために1要素を後続に追加\r
+ return scanEdge(temp,length+1,i_noise_th,o_edge_index);\r
+ }\r
+ private int scanEdge(int[] i_pixels,int i_length,int i_noise_th,double[] o_out)\r
+ {\r
+ int points=0;\r
+ final int length=i_length;\r
+ //エッジ1区間を抜き出す\r
+ for(int i2=0;i2<length;i2++){\r
+ int t=i_pixels[i2];\r
+ if(t>i_noise_th){\r
+ int st=i2;\r
+ i2++;\r
+ for(;i2<length;i2++){\r
+ t=i_pixels[i2];\r
+ if(t<=0){\r
+ //(st - i2で1区間)\r
+ //エッジ位置は区間の中央にする。\r
+ o_out[points]=(st+i2)/2.0;\r
+ points++;\r
+ if(t<0){\r
+ //マイナスであれば、0を補完する\r
+ i2--;\r
+ i_pixels[i2]=0;\r
+ }\r
+ break;\r
+ }\r
+\r
+ }\r
+ }else if(t<-i_noise_th){\r
+ int st=i2;\r
+ i2++;\r
+ for(;i2<length;i2++){\r
+ t=i_pixels[i2];\r
+ if(t>=0){\r
+ //(st - i2で1区間)\r
+ //エッジ位置は区間の中央にする。\r
+ o_out[points]=(st+i2)/2.0;\r
+ points++;\r
+ if(t>0){\r
+ //プラスであれば、0を補完する\r
+ i2--;\r
+ i_pixels[i2]=0;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return points;\r
+ } \r
+ /**\r
+ * 指定した配列をノイズパターンとして、ノイズ値を計算します。\r
+ * このノイズ値は、scanEdgeのノイズ値として使用できます。\r
+ * @param i_pixels\r
+ * @param i_length\r
+ * @return\r
+ */\r
+ public int getNoiseValue(int[] i_pixels,int i_length)\r
+ {\r
+ //1回微分して、その最大値と最小値を計算\r
+ int length=i_length-1;\r
+ int max_value,min_value;\r
+ max_value=min_value=0;\r
+ for(int i2=0;i2<length;i2++){\r
+ int t=i_pixels[i2+1]-i_pixels[i2];\r
+ if(t>max_value){\r
+ max_value=t;\r
+ }\r
+ if(t<min_value){\r
+ min_value=t;\r
+ }\r
+ }\r
+ return (-min_value>max_value)?-min_value:max_value;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.vertexdetect;\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.*;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+/**\r
+ * PCAではなく、頂点座標そのものからSquare位置を計算するクラス\r
+ *\r
+ */\r
+public class NyARVertexDetector implements INyARSquareContourDetector\r
+{\r
+ private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
+\r
+ private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
+ private final int _width;\r
+ private final int _height;\r
+\r
+ private final NyARLabeling_ARToolKit _labeling;\r
+\r
+ private final NyARLabelingImage _limage;\r
+\r
+ private final LabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new LabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
+ private final Coord2Linear _sqconvertor;\r
+ private final ContourPickup _cpickup=new ContourPickup();\r
+\r
+ /**\r
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARVertexDetector(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
+ {\r
+ this._width = i_size.w;\r
+ this._height = i_size.h;\r
+ this._labeling = new NyARLabeling_ARToolKit();\r
+ this._limage = new NyARLabelingImage(this._width, this._height);\r
+ this._sqconvertor=new Coord2Linear(i_size,i_dist_factor_ref); \r
+\r
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
+ int number_of_coord = (this._width + this._height) * 2;\r
+\r
+ // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
+ this._max_coord = number_of_coord;\r
+ this._xcoord = new int[number_of_coord * 2];\r
+ this._ycoord = new int[number_of_coord * 2];\r
+ }\r
+\r
+ private final int _max_coord;\r
+ private final int[] _xcoord;\r
+ private final int[] _ycoord;\r
+\r
+ /**\r
+ * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double\r
+ * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。\r
+ * \r
+ * @param i_raster\r
+ * 解析する2値ラスタイメージを指定します。\r
+ * @param o_square_stack\r
+ * 抽出した正方形候補を格納するリスト\r
+ * @throws NyARException\r
+ */\r
+ public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
+ {\r
+ final NyARLabelingImage limage = this._limage;\r
+\r
+ // 初期化\r
+\r
+ // マーカーホルダをリセット\r
+ o_square_stack.clear();\r
+\r
+ // ラベリング\r
+ this._labeling.labeling(i_raster,this._limage);\r
+\r
+ // ラベル数が0ならここまで\r
+ final int label_num = limage.getLabelStack().getLength();\r
+ if (label_num < 1) {\r
+ return;\r
+ }\r
+ \r
+\r
+ final NyARLabelingLabelStack stack = limage.getLabelStack();\r
+ // ラベルを大きい順に整列\r
+ stack.sortByArea();\r
+ \r
+ final NyARLabelingLabel[] labels = stack.getArray();\r
+\r
+ // デカいラベルを読み飛ばし\r
+ int i;\r
+ for (i = 0; i < label_num; i++) {\r
+ // 検査対象内のラベルサイズになるまで無視\r
+ if (labels[i].area <= AR_AREA_MAX) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ final int xsize = this._width;\r
+ final int ysize = this._height;\r
+ final int[] xcoord = this._xcoord;\r
+ final int[] ycoord = this._ycoord;\r
+ final int coord_max = this._max_coord;\r
+ final LabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
+ int label_area;\r
+ NyARLabelingLabel label_pt;\r
+\r
+ //重なりチェッカの最大数を設定\r
+ overlap.setMaxLabels(label_num);\r
+\r
+ for (; i < label_num; i++) {\r
+ label_pt = labels[i];\r
+ label_area = label_pt.area;\r
+ // 検査対象サイズよりも小さくなったら終了\r
+ if (label_area < AR_AREA_MIN) {\r
+ break;\r
+ }\r
+ // クリップ領域が画面の枠に接していれば除外\r
+ if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){\r
+ continue;\r
+ }\r
+ if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){\r
+ continue;\r
+ }\r
+ // 既に検出された矩形との重なりを確認\r
+ if (!overlap.check(label_pt)) {\r
+ // 重なっているようだ。\r
+ continue;\r
+ }\r
+ // 輪郭を取得\r
+ final int coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
+ if (coord_num == coord_max) {\r
+ // 輪郭が大きすぎる。\r
+ continue;\r
+ }\r
+ //輪郭分析用に正規化する。\r
+ final int vertex1 = Coord2Linear.normalizeCoord(xcoord, ycoord, coord_num);\r
+\r
+ //ここから先が輪郭分析\r
+ NyARSquare square_ptr = o_square_stack.prePush();\r
+ if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
+ o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
+ continue; \r
+ }\r
+ // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
+ overlap.push(label_pt);\r
+ } \r
+ return;\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JOGL sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import java.awt.event.WindowAdapter;\r
+import java.awt.event.WindowEvent;\r
+import java.awt.*;\r
+\r
+import javax.media.Buffer;\r
+\r
+import javax.media.opengl.GL;\r
+import javax.media.opengl.GLAutoDrawable;\r
+import javax.media.opengl.GLEventListener;\r
+import javax.media.opengl.GLCanvas;\r
+\r
+import com.sun.opengl.util.Animator;\r
+\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+/**\r
+ * simpleLiteと同じようなテストプログラム\r
+ * 出来る限りARToolKitのサンプルと似せて作ってあります。\r
+ * 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。\r
+ * \r
+ */\r
+public class JavaSimpleLite_X2 implements GLEventListener, JmfCaptureListener\r
+{\r
+ private final String CARCODE_FILE = "../../Data/patt.hiro";\r
+\r
+ private final String PARAM_FILE = "../../Data/camera_para.dat";\r
+\r
+ private final static int SCREEN_X = 320;\r
+\r
+ private final static int SCREEN_Y = 240;\r
+\r
+ private Animator _animator;\r
+\r
+ private GLNyARRaster_RGB _cap_image;\r
+\r
+ private JmfCaptureDevice _capture;\r
+\r
+ private GL _gl;\r
+\r
+ private NyARGLUtil _glnya;\r
+\r
+ //NyARToolkit関係\r
+ private NyARSingleDetectMarker_X2 _nya;\r
+\r
+ private NyARParam _ar_param;\r
+\r
+ /**\r
+ * 立方体を書く\r
+ *\r
+ */\r
+ void drawCube()\r
+ {\r
+ // Colour cube data.\r
+ int polyList = 0;\r
+ float fSize = 0.5f;//マーカーサイズに対して0.5倍なので、4cmの立方体\r
+ int f, i;\r
+ float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };\r
+ float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };\r
+ int cube_num_faces = 6;\r
+ short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };\r
+\r
+ if (polyList == 0) {\r
+ polyList = _gl.glGenLists(1);\r
+ _gl.glNewList(polyList, GL.GL_COMPILE);\r
+ _gl.glBegin(GL.GL_QUADS);\r
+ for (f = 0; f < cube_num_faces; f++)\r
+ for (i = 0; i < 4; i++) {\r
+ _gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);\r
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ }\r
+ _gl.glEnd();\r
+ _gl.glColor3f(0.0f, 0.0f, 0.0f);\r
+ for (f = 0; f < cube_num_faces; f++) {\r
+ _gl.glBegin(GL.GL_LINE_LOOP);\r
+ for (i = 0; i < 4; i++)\r
+ _gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ _gl.glEnd();\r
+ }\r
+ _gl.glEndList();\r
+ }\r
+\r
+ _gl.glPushMatrix(); // Save world coordinate system.\r
+ _gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.\r
+ _gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.\r
+ _gl.glDisable(GL.GL_LIGHTING); // Just use colours.\r
+ _gl.glCallList(polyList); // Draw the cube.\r
+ _gl.glPopMatrix(); // Restore world coordinate system.\r
+\r
+ }\r
+\r
+ public JavaSimpleLite_X2()\r
+ {\r
+ NyMath.initialize();\r
+ Frame frame = new Frame("Java simpleLite with NyARToolkit");\r
+\r
+ // 3Dを描画するコンポーネント\r
+ GLCanvas canvas = new GLCanvas();\r
+ frame.add(canvas);\r
+ canvas.addGLEventListener(this);\r
+ frame.addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+\r
+ frame.setVisible(true);\r
+ Insets ins = frame.getInsets();\r
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
+ }\r
+\r
+ public void init(GLAutoDrawable drawable)\r
+ {\r
+ _gl = drawable.getGL();\r
+ _gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+ //NyARToolkitの準備\r
+ try {\r
+ //キャプチャの準備\r
+ JmfCaptureDeviceList list=new JmfCaptureDeviceList();\r
+ _capture=list.getDevice(0);\r
+ _capture.setCaptureFormat(SCREEN_X, SCREEN_Y, 15f);\r
+ _capture.setOnCapture(this);\r
+ //NyARToolkitの準備\r
+ _ar_param = new NyARParam();\r
+ NyARCode ar_code = new NyARCode(16, 16);\r
+ _ar_param.loadARParamFromFile(PARAM_FILE);\r
+ _ar_param.changeScreenSize(SCREEN_X, SCREEN_Y);\r
+ ar_code.loadARPattFromFile(CARCODE_FILE);\r
+ //NyARToolkit用の支援クラス\r
+ _glnya = new NyARGLUtil(_gl);\r
+ //GL対応のRGBラスタオブジェクト\r
+ _cap_image = new GLNyARRaster_RGB(_ar_param,_capture.getCaptureFormat());\r
+ _nya = new NyARSingleDetectMarker_X2(_ar_param, ar_code, 80.0,this._cap_image.getBufferReader().getBufferType());\r
+ _nya.setContinueMode(false);//ここをtrueにすると、transMatContinueモード(History計算)になります。\r
+ //キャプチャ開始\r
+ _capture.start();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ //カメラパラメータの計算\r
+ _glnya.toCameraFrustumRH(_ar_param,_camera_projection);\r
+ _animator = new Animator(drawable);\r
+\r
+ _animator.start();\r
+\r
+ }\r
+\r
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
+ {\r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
+ _gl.glViewport(0, 0, width, height);\r
+\r
+ //視体積の設定\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadIdentity();\r
+ //見る位置\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ _gl.glLoadIdentity();\r
+ }\r
+ private double[] _camera_projection=new double[16];\r
+ private NyARTransMatResult __display_transmat_result=new NyARTransMatResult();\r
+ private double[] __display_wk=new double[16];\r
+ public void display(GLAutoDrawable drawable)\r
+ {\r
+ NyARTransMatResult transmat_result=__display_transmat_result;\r
+ try {\r
+ if (!_cap_image.hasData()) {\r
+ return;\r
+ }\r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame. \r
+ //画像チェックしてマーカー探して、背景を書く\r
+ boolean is_marker_exist;\r
+ synchronized (_cap_image) {\r
+ is_marker_exist = _nya.detectMarkerLite(_cap_image, 110);\r
+ //背景を書く\r
+ _glnya.drawBackGround(_cap_image, 1.0);\r
+ }\r
+ //マーカーがあれば、立方体を描画\r
+ if (is_marker_exist) {\r
+ //マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。\r
+ // Projection transformation.\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadMatrixd(_camera_projection, 0);\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ // Viewing transformation.\r
+ _gl.glLoadIdentity();\r
+ //変換行列を取得\r
+ _nya.getTransmationMatrix(transmat_result);\r
+ //変換行列をOpenGL形式に変換\r
+ _glnya.toCameraViewRH(transmat_result, __display_wk);\r
+ _gl.glLoadMatrixd(__display_wk, 0);\r
+\r
+ // All other lighting and geometry goes here.\r
+ drawCube();\r
+ }\r
+ Thread.sleep(1);//タスク実行権限を一旦渡す\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+ synchronized (_cap_image) {\r
+ _cap_image.setBuffer(i_buffer);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
+ {\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ new JavaSimpleLite_X2();\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+/**\r
+ * ARMat構造体に対応するクラス typedef struct { double *m; int row; int clm; }ARMat;\r
+ * \r
+ */\r
+public class NyARFixedFloat16Mat\r
+{\r
+ /**\r
+ * 配列サイズと行列サイズは必ずしも一致しないことに注意 返された配列のサイズを行列の大きさとして使わないこと!\r
+ * \r
+ */\r
+ protected long[][] m;\r
+ private int clm, row;\r
+\r
+ /**\r
+ * デフォルトコンストラクタは機能しません。\r
+ * \r
+ * @throws NyARException\r
+ */\r
+ protected NyARFixedFloat16Mat() throws NyARException\r
+ {\r
+ throw new NyARException();\r
+ }\r
+\r
+ public NyARFixedFloat16Mat(int i_row, int i_clm)\r
+ {\r
+ this.m = new long[i_row][i_clm];\r
+ clm = i_clm;\r
+ row = i_row;\r
+ return;\r
+ }\r
+ public int getClm()\r
+ {\r
+ return clm;\r
+ }\r
+ public int getRow()\r
+ {\r
+ return row;\r
+ }\r
+ /**\r
+ * 行列をゼロクリアする。\r
+ */\r
+ public void zeroClear()\r
+ {\r
+ int i, i2;\r
+ // For順変更OK\r
+ for (i = row - 1; i >= 0; i--) {\r
+ for (i2 = clm - 1; i2 >= 0; i2--) {\r
+ m[i][i2] = 0;\r
+ }\r
+ }\r
+ }\r
+ public long[][] getArray()\r
+ {\r
+ return this.m;\r
+ }\r
+ // public void getRowVec(int i_row,NyARVec o_vec)\r
+ // {\r
+ // o_vec.set(this.m[i_row],this.clm);\r
+ // }\r
+ /**\r
+ * aとbの積を自分自身に格納する。arMatrixMul()の代替品\r
+ * \r
+ * @param a\r
+ * @param b\r
+ * @throws NyARException\r
+ */\r
+ public void matrixMul(NyARFixedFloat16Mat a, NyARFixedFloat16Mat b) throws NyARException\r
+ {\r
+ if (a.clm != b.row || this.row != a.row || this.clm != b.clm) {\r
+ throw new NyARException();\r
+ }\r
+ long w;\r
+ int r, c, i;\r
+ long[][] am = a.m, bm = b.m, dm = this.m;\r
+ // For順変更禁止\r
+ for (r = 0; r < this.row; r++) {\r
+ for (c = 0; c < this.clm; c++) {\r
+ w = 0L;// dest.setARELEM0(r, c,0.0);\r
+ for (i = 0; i < a.clm; i++) {\r
+ w += (am[r][i] * bm[i][c])>>16;// ARELEM0(dest, r, c) +=ARELEM0(a, r, i) * ARELEM0(b,i, c);\r
+ }\r
+ dm[r][c] = w;\r
+ }\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point3d;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+\r
+class NyARCustomMatrix extends NyARMat\r
+{\r
+ public NyARCustomMatrix(int i_row, int i_clm)\r
+ {\r
+ super(i_row,i_clm);\r
+ return;\r
+ }\r
+ public void copyFrom(NyARFixedFloat16Mat i_mat) throws NyARException\r
+ {\r
+ long[][] ptr;\r
+ int r,c;\r
+ // For順変更禁止\r
+ for (r = 0; r < this.row; r++){\r
+ ptr=i_mat.getArray();\r
+ for (c = 0; c < this.clm; c++){\r
+ this._m[c][r]=(double)ptr[c][r]/0x10000;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+}\r
+/**\r
+ * 平行移動量を計算するクラス\r
+ * \r
+ * NyARPerspectiveProjectionMatrixに直接アクセスしてる場所があるけど、\r
+ * この辺の計算はNyARPerspectiveProjectionMatrixクラスの関数にして押し込む予定。\r
+ *\r
+ */\r
+public class NyARFixedFloatFitVecCalculator\r
+{\r
+ private final NyARFixedFloat16Mat _mat_b = new NyARFixedFloat16Mat(3,8);//3,NUMBER_OF_VERTEX*2\r
+ private final NyARFixedFloat16Mat _mat_a = new NyARFixedFloat16Mat(8,3);/*NUMBER_OF_VERTEX,3*/\r
+ private final NyARFixedFloat16Mat _mat_d = new NyARFixedFloat16Mat(3,3);\r
+ private final NyARCustomMatrix _mat_d2=new NyARCustomMatrix(3,3);\r
+ private final NyARPerspectiveProjectionMatrix _projection_mat;\r
+ private final NyARFixedFloatIdeal2Observ _distortionfactor;\r
+\r
+\r
+// private NyARDoublePoint2d[] _vertex_2d_ref;\r
+ public NyARFixedFloatFitVecCalculator(final NyARPerspectiveProjectionMatrix i_projection_mat_ref,final NyARCameraDistortionFactor i_distortion_ref)\r
+ {\r
+ // 変換マトリクスdとbの準備(arGetTransMatSubの一部)\r
+ final long[][] a_array = this._mat_a.getArray();\r
+ final long[][] b_array = this._mat_b.getArray();\r
+\r
+ //変換用行列のcpara固定値の部分を先に初期化してしまう。\r
+ for (int i = 0; i < 4; i++) {\r
+ final int x2 = i * 2;\r
+ a_array[x2][0] = b_array[0][x2] =(long)(i_projection_mat_ref.m00*NyMath.FIXEDFLOAT16_1);// mat_a->m[j*6+0]=mat_b->m[num*0+j*2] =cpara[0][0];\r
+ a_array[x2][1] = b_array[1][x2] =(long)(i_projection_mat_ref.m01*NyMath.FIXEDFLOAT16_1);// mat_a->m[j*6+1]=mat_b->m[num*2+j*2]=cpara[0][1];\r
+ a_array[x2 + 1][0] = b_array[0][x2 + 1] =0;// mat_a->m[j*6+3] =mat_b->m[num*0+j*2+1]= 0.0;\r
+ a_array[x2 + 1][1] = b_array[1][x2 + 1] =(long)(i_projection_mat_ref.m11*NyMath.FIXEDFLOAT16_1);// mat_a->m[j*6+4] =mat_b->m[num*2+j*2+1]= cpara[1][1];\r
+ }\r
+ this._projection_mat=i_projection_mat_ref;\r
+ this._distortionfactor=new NyARFixedFloatIdeal2Observ(i_distortion_ref);\r
+ return;\r
+ }\r
+ private final NyARFixedFloat16Point2d[] _fitsquare_vertex=NyARFixedFloat16Point2d.createArray(4);;\r
+ private NyARFixedFloatTransOffset _offset_square;\r
+ public void setOffsetSquare(NyARFixedFloatTransOffset i_offset)\r
+ {\r
+ this._offset_square=i_offset;\r
+ return;\r
+ }\r
+ public NyARFixedFloat16Point2d[] getFitSquare()\r
+ {\r
+ return this._fitsquare_vertex;\r
+ }\r
+ public NyARFixedFloatTransOffset getOffsetVertex()\r
+ {\r
+ return this._offset_square;\r
+ }\r
+\r
+ /**\r
+ * 適合させる矩形座標を指定します。\r
+ * @param i_square_vertex\r
+ * @throws NyARException\r
+ */\r
+ public void setFittedSquare(NyARFixedFloat16Point2d[] i_square_vertex) throws NyARException\r
+ {\r
+ final NyARFixedFloat16Point2d[] vertex=_fitsquare_vertex;\r
+ for(int i=0;i<4;i++){\r
+ this._distortionfactor.ideal2Observ(i_square_vertex[i], vertex[i]);\r
+ } \r
+ \r
+ final long cpara02=(long)(this._projection_mat.m02*NyMath.FIXEDFLOAT16_1);\r
+ final long cpara12=(long)(this._projection_mat.m12*NyMath.FIXEDFLOAT16_1); \r
+ final NyARFixedFloat16Mat mat_d=_mat_d;\r
+ final NyARFixedFloat16Mat mat_a=this._mat_a;\r
+ final NyARFixedFloat16Mat mat_b=this._mat_b;\r
+ final long[][] a_array = mat_a.getArray();\r
+ final long[][] b_array = mat_b.getArray();\r
+ for (int i = 0; i < 4; i++) {\r
+ final int x2 = i * 2; \r
+ a_array[x2][2] = b_array[2][x2] = (long)((cpara02 - vertex[i].x));// mat_a->m[j*6+2]=mat_b->m[num*4+j*2]=cpara[0][2]-pos2d[j][0];\r
+ a_array[x2 + 1][2] = b_array[2][x2 + 1] = (long)((cpara12 - vertex[i].y));// mat_a->m[j*6+5]=mat_b->m[num*4+j*2+1]=cpara[1][2]-pos2d[j][1];\r
+ }\r
+ // mat_d\r
+ mat_d.matrixMul(mat_b, mat_a);\r
+ this._mat_d2.copyFrom(mat_d);\r
+ this._mat_d2.matrixSelfInv(); \r
+ return;\r
+ }\r
+ private final NyARFixedFloat16Mat _mat_e = new NyARFixedFloat16Mat(3, 1);\r
+ private final NyARFixedFloat16Mat __calculateTransferVec_mat_c = new NyARFixedFloat16Mat(8, 1);//NUMBER_OF_VERTEX * 2, 1\r
+ private final NyARFixedFloat16Point3d[] __calculateTransfer_point3d=NyARFixedFloat16Point3d.createArray(4); \r
+ \r
+ /**\r
+ * 現在のオフセット矩形、適合先矩形と、回転行列から、平行移動量を計算します。\r
+ * @param i_rotation\r
+ * @param o_transfer\r
+ * @throws NyARException\r
+ */\r
+ final public void calculateTransfer(NyARFixedFloatRotMatrix i_rotation,NyARFixedFloat16Point3d o_transfer) throws NyARException\r
+ {\r
+ assert(this._offset_square!=null);\r
+ final long cpara00=(long)(this._projection_mat.m00*NyMath.FIXEDFLOAT16_1);\r
+ final long cpara01=(long)(this._projection_mat.m01*NyMath.FIXEDFLOAT16_1);\r
+ final long cpara02=(long)(this._projection_mat.m02*NyMath.FIXEDFLOAT16_1);\r
+ final long cpara11=(long)(this._projection_mat.m11*NyMath.FIXEDFLOAT16_1);\r
+ final long cpara12=(long)(this._projection_mat.m12*NyMath.FIXEDFLOAT16_1);\r
+ \r
+ final NyARFixedFloat16Point3d[] point3d=this.__calculateTransfer_point3d;\r
+ final NyARFixedFloat16Point3d[] vertex3d=this._offset_square.vertex; \r
+ final NyARFixedFloat16Point2d[] vertex2d=this._fitsquare_vertex;\r
+ final NyARFixedFloat16Mat mat_c = this.__calculateTransferVec_mat_c;// 次処理で値をもらうので、初期化の必要は無い。\r
+ \r
+ final long[][] c_array = mat_c.getArray();\r
+ \r
+ \r
+ //(3D座標?)を一括請求\r
+ i_rotation.getPoint3dBatch(vertex3d,point3d,4);\r
+ for (int i = 0; i < 4; i++) {\r
+ final int x2 = i+i;\r
+ final NyARFixedFloat16Point3d point3d_ptr=point3d[i];\r
+ //透視変換?\r
+ c_array[x2][0] =(long)((point3d_ptr.z * vertex2d[i].x - cpara00 * point3d_ptr.x - cpara01 * point3d_ptr.y - cpara02 * point3d_ptr.z)>>16);// mat_c->m[j*2+0] = wz*pos2d[j][0]-cpara[0][0]*wx-cpara[0][1]*wy-cpara[0][2]*wz;\r
+ c_array[x2 + 1][0] =(long)((point3d_ptr.z * vertex2d[i].y - cpara11 * point3d_ptr.y - cpara12 * point3d_ptr.z)>>16);// mat_c->m[j*2+1]= wz*pos2d[j][1]-cpara[1][1]*wy-cpara[1][2]*wz;\r
+ }\r
+ this._mat_e.matrixMul(this._mat_b, mat_c);\r
+ final double[][] d2=this._mat_d2.getArray();\r
+ final long[][] e2=this._mat_e.getArray();\r
+ \r
+ \r
+ //this._mat_f.matrixMul(this._mat_d, this._mat_e);\r
+\r
+ // double[] trans=wk_arGetTransMatSub_trans;//double trans[3];\r
+ o_transfer.x=(long)(d2[0][0]*e2[0][0]+d2[0][1]*e2[1][0]+d2[0][2]*e2[2][0]);\r
+ o_transfer.y=(long)(d2[1][0]*e2[0][0]+d2[1][1]*e2[1][0]+d2[1][2]*e2[2][0]);\r
+ o_transfer.z=(long)(d2[2][0]*e2[0][0]+d2[2][1]*e2[1][0]+d2[2][2]*e2[2][0]);\r
+ return;\r
+ }\r
+ \r
+ \r
+ \r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point2d;\r
+\r
+public class NyARFixedFloatIdeal2Observ\r
+{\r
+ private double[] _factor=new double[4];\r
+ public NyARFixedFloatIdeal2Observ(NyARCameraDistortionFactor i_distfactor)\r
+ {\r
+ i_distfactor.getValue(this._factor);\r
+ return;\r
+ } \r
+ public void ideal2ObservBatch(final NyARDoublePoint2d[] i_in, NyARFixedFloat16Point2d[] o_out, int i_size)\r
+ {\r
+ double x, y;\r
+ final double d0 = this._factor[0];\r
+ final double d1 = this._factor[1];\r
+ final double d3 = this._factor[3];\r
+ final double d2_w = this._factor[2] / 100000000.0;\r
+ for (int i = 0; i < i_size; i++) {\r
+ x = (i_in[i].x - d0) * d3;\r
+ y = (i_in[i].y - d1) * d3;\r
+ if (x == 0.0 && y == 0.0) {\r
+ o_out[i].x = (long)(d0*NyMath.FIXEDFLOAT16_1);\r
+ o_out[i].y = (long)(d1*NyMath.FIXEDFLOAT16_1);\r
+ } else {\r
+ final double d = 1.0 - d2_w * (x * x + y * y);\r
+ o_out[i].x = (long)((x * d + d0)*NyMath.FIXEDFLOAT16_1);\r
+ o_out[i].y = (long)((y * d + d1)*NyMath.FIXEDFLOAT16_1);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ public void ideal2Observ(final NyARFixedFloat16Point2d i_in, NyARFixedFloat16Point2d o_out)\r
+ {\r
+ final double f0=this._factor[0];\r
+ final double f1=this._factor[1];\r
+ final double x = (((double)i_in.x/NyMath.FIXEDFLOAT16_1) - f0) * this._factor[3];\r
+ final double y = (((double)i_in.y/NyMath.FIXEDFLOAT16_1) - f1) * this._factor[3];\r
+ if (x == 0.0 && y == 0.0) {\r
+ o_out.x = (long)(f0*NyMath.FIXEDFLOAT16_1);\r
+ o_out.y = (long)(f1*NyMath.FIXEDFLOAT16_1);\r
+ } else {\r
+ final double d = 1.0 - this._factor[2] / 100000000.0 * (x * x + y * y);\r
+ o_out.x = (long)((x * d + f0)*NyMath.FIXEDFLOAT16_1);\r
+ o_out.y = (long)((y * d + f1)*NyMath.FIXEDFLOAT16_1);\r
+ }\r
+ return;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+/**\r
+ * 歪み成分マップを使用するINyARCameraDistortionFactor\r
+ * 内部マップをint(1:15:16)フォーマットの固定小数点で保持する。\r
+ * 固定小数点で値を提供するインタフェイスを持ちます。\r
+ */\r
+final public class NyARFixedFloatObserv2IdealMap\r
+{\r
+ private double[] _factor=new double[4];\r
+ private int _stride;\r
+ private int[] _mapx;\r
+ private int[] _mapy;\r
+ public NyARFixedFloatObserv2IdealMap(double[] i_map_x,double[] i_map_y,NyARIntSize i_screen_size)\r
+ {\r
+ \r
+ }\r
+ \r
+ public NyARFixedFloatObserv2IdealMap(NyARCameraDistortionFactor i_distfactor,NyARIntSize i_screen_size)\r
+ {\r
+ NyARDoublePoint2d opoint=new NyARDoublePoint2d();\r
+ this._mapx=new int[i_screen_size.w*i_screen_size.h];\r
+ this._mapy=new int[i_screen_size.w*i_screen_size.h];\r
+ this._stride=i_screen_size.w;\r
+ int ptr=i_screen_size.h*i_screen_size.w-1;\r
+ //歪みマップを構築\r
+ for(int i=i_screen_size.h-1;i>=0;i--)\r
+ {\r
+ for(int i2=i_screen_size.w-1;i2>=0;i2--)\r
+ {\r
+ i_distfactor.observ2Ideal(i2,i,opoint);\r
+ this._mapx[ptr]=(int)(opoint.x*65536);\r
+ this._mapy[ptr]=(int)(opoint.y*65536);\r
+ ptr--;\r
+ }\r
+ }\r
+ i_distfactor.getValue(this._factor);\r
+ return;\r
+ } \r
+ /**\r
+ * 点集合のi_start~i_numまでの間から、最大i_sample_count個の頂点を取得して返します。\r
+ * i_sample_countは偶数である必要があります。\r
+ * @param i_x_coord\r
+ * @param i_y_coord\r
+ * @param i_start\r
+ * @param i_num\r
+ * @param o_x_coord\r
+ * @param o_y_coord\r
+ * @param i_sample_count\r
+ * @return\r
+ */\r
+ public int observ2IdealSampling(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, int[] o_x_coord,int[] o_y_coord,int i_sample_count)\r
+ {\r
+ assert(i_sample_count%2==0);\r
+ int idx;\r
+ if (i_num < i_sample_count)\r
+ {\r
+ for (int i = i_num - 1; i >= 0; i--)\r
+ {\r
+ idx = i_x_coord[i_start + i] + i_y_coord[i_start + i] * this._stride;\r
+ o_x_coord[i] = this._mapx[idx];\r
+ o_y_coord[i] = this._mapy[idx];\r
+ }\r
+ return i_num;\r
+ }\r
+ else\r
+ {\r
+ //サンプリング個数分の点を、両端から半分づつ取ってくる。\r
+ int st = i_start;\r
+ int ed = i_start + i_num - 1;\r
+ for (int i = i_sample_count - 1; i >= 0; i -= 2)\r
+ {\r
+ idx = i_x_coord[st] + i_y_coord[st] * this._stride;\r
+ o_x_coord[i] = this._mapx[idx];\r
+ o_y_coord[i] = this._mapy[idx];\r
+ idx = i_x_coord[ed] + i_y_coord[ed] * this._stride;\r
+ o_x_coord[i - 1] = this._mapx[idx];\r
+ o_y_coord[i - 1] = this._mapy[idx];\r
+ ed--;\r
+ st++;\r
+ }\r
+ return i_sample_count;\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.pca2d.*;\r
+/**\r
+ * 64bit(小数部16bit)の固定小数点を利用したPCA関数\r
+ *\r
+ */\r
+public class NyARFixedFloatPca2d implements INyARPca2d\r
+{\r
+// private static final double PCA_EPS = 1e-6; // #define EPS 1e-6\r
+\r
+ private static final int PCA_MAX_ITER = 100; // #define MAX_ITER 100\r
+ /**\r
+ * static int QRM( ARMat *a, ARVec *dv )の代替関数\r
+ * \r
+ * @param a\r
+ * @param dv\r
+ * @throws NyARException\r
+ */\r
+ private static void PCA_QRM(NyARI64Matrix22 o_matrix, NyARI64Point2d dv) throws NyARException\r
+ {\r
+ long abs_x;\r
+ long w, t, s, x, y, c;\r
+ long ev1;\r
+ long dv_x,dv_y;\r
+ long mat00,mat01,mat10,mat11;\r
+ // <this.vecTridiagonalize2d(i_mat, dv, ev);>\r
+ dv_x =o_matrix.m00;// this.m[dim - 2][dim - 2];// d.v[dim-2]=a.m[dim-2][dim-2];//d->v[dim-2]=a->m[(dim-2)*dim+(dim-2)];\r
+ ev1 =o_matrix.m01;// this.m[dim - 2][dim - 1];// e.v[dim-2+i_e_start]=a.m[dim-2][dim-1];//e->v[dim-2] = a->m[(dim-2)*dim+(dim-1)];\r
+ dv_y =o_matrix.m11;// this.m[dim - 1][dim - 1];// d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] =a->m[(dim-1)*dim+(dim-1)];\r
+ // 単位行列にする。\r
+ mat00 = mat11 = (1<<16);\r
+ mat01 = mat10 = 0;\r
+ // </this.vecTridiagonalize2d(i_mat, dv, ev);>\r
+\r
+ // int j = 1;\r
+ // // while(j>0 && fabs(ev->v[j])>EPS*(fabs(dv->v[j-1])+fabs(dv->v[j])))\r
+ // while (j > 0 && Math.abs(ev1) > PCA_EPS * (Math.abs(dv.x) + Math.abs(dv.y))) {\r
+ // j--;\r
+ // }\r
+ // if (j == 0) {\r
+ int iter = 0;\r
+ do {\r
+ iter++;\r
+ if (iter > PCA_MAX_ITER) {\r
+ break;\r
+ }\r
+ w = (dv_x - dv_y) / 2L;//S16\r
+ t = (ev1 * ev1)>>16;// t = ev->v[h] * ev->v[h];\r
+ s = NyMath.sqrtFixdFloat16(((w * w)>>16) + t);\r
+ if (w < 0) {\r
+ s = -s;\r
+ }\r
+ x = dv_x - dv_y + (t<<16) / (w + s);// x = dv->v[j] -dv->v[h] +t/(w+s);\r
+ y = ev1;// y = ev->v[j+1];\r
+\r
+ abs_x=(x>0?x:-x);\r
+ if (abs_x >= (y>0?y:-y)) { //if (Math.abs(x) >= Math.abs(y)) {\r
+ if ((abs_x>>16) > 0) {\r
+ t = -(y<<16) / x;\r
+ c = (1L<<32) / NyMath.sqrtFixdFloat16(((t * t)>>16) + (1L<<16));\r
+ s = (t * c)>>16;\r
+ } else {\r
+ c = (1L<<16);\r
+ s = 0;\r
+ }\r
+ } else {\r
+ t = -(x<<16) / y;\r
+ s = (1L<<32) / NyMath.sqrtFixdFloat16(((t * t)>>16) + (1L<<16));\r
+ c = (t * s)>>16;\r
+ }\r
+ w = dv_x - dv_y;// w = dv->v[k] -dv->v[k+1];\r
+ t = (((w * s + 2L * c * ev1)>>16) * s)>>16;// t = (w * s +2 * c *ev->v[k+1]) *s;\r
+ dv_x -= t;// dv->v[k] -= t;\r
+ dv_y += t;// dv->v[k+1] += t;\r
+ ev1 += (s * ((c * w - 2L * s * ev1)>>16)>>16);// ev->v[k+1]+= s * (c* w- 2* s *ev->v[k+1]);\r
+\r
+ x = mat00;// x = a->m[k*dim+i];\r
+ y = mat10;// y = a->m[(k+1)*dim+i];\r
+ mat00 = (c * x - s * y)>>16;// a->m[k*dim+i] = c * x - s* y;\r
+ mat10 = (s * x + c * y)>>16;// a->m[(k+1)*dim+i] = s* x + c * y;\r
+ \r
+ x = mat01;// x = a->m[k*dim+i];\r
+ y = mat11;// y = a->m[(k+1)*dim+i];\r
+ mat01 = (c * x - s * y)>>16;// a->m[k*dim+i] = c * x - s* y;\r
+ mat11 = (s * x + c * y)>>16;// a->m[(k+1)*dim+i] = s* x + c * y;\r
+ } while (((ev1>0?ev1:-ev1)>>16) > ((((dv_x>0?dv_x:-dv_x) + (dv_y>0?dv_y:-dv_y))>>16)/1000000L));\r
+ // }\r
+\r
+ t = dv_x;// t = dv->v[h];\r
+ if (dv_y > t) {// if( dv->v[i] > t ) {\r
+ t = dv_y;// t = dv->v[h];\r
+ dv_y = dv_x;// dv->v[h] = dv->v[k];\r
+ dv_x = t;// dv->v[k] = t;\r
+ // 行の入れ替え\r
+ o_matrix.m00 = mat10;\r
+ o_matrix.m01 = mat11;\r
+ o_matrix.m10 = mat00; \r
+ o_matrix.m11 = mat01;\r
+ \r
+ } else {\r
+ // 行の入れ替えはなし\r
+ o_matrix.m00 = mat00;\r
+ o_matrix.m01 = mat01;\r
+ o_matrix.m10 = mat10; \r
+ o_matrix.m11 = mat11;\r
+ }\r
+ dv.x=dv_x;\r
+ dv.y=dv_y;\r
+ return; \r
+ }\r
+\r
+ /**\r
+ * static int PCA( ARMat *input, ARMat *output, ARVec *ev )\r
+ * \r
+ * @param output\r
+ * @param o_ev\r
+ * @throws NyARException\r
+ */\r
+ /**\r
+ * static int PCA( ARMat *input, ARMat *output, ARVec *ev )\r
+ * \r
+ * @param output\r
+ * @param o_ev\r
+ * @throws NyARException\r
+ */\r
+ private void PCA_PCA(int[] i_x,int[] i_y,int i_number_of_data,NyARI64Matrix22 o_matrix, NyARI64Point2d o_ev,NyARI64Point2d o_mean) throws NyARException\r
+ {\r
+ // double[] mean_array=mean.getArray();\r
+ // mean.zeroClear();\r
+\r
+ //PCA_EXの処理\r
+ long sx = 0;\r
+ long sy = 0;\r
+ for (int i = 0; i < i_number_of_data; i++) {\r
+ sx += i_x[i];//S16\r
+ sy += i_y[i];//S16\r
+ }\r
+ sx = sx / i_number_of_data;//S16\r
+ sy = sy / i_number_of_data;//S16\r
+ \r
+ //PCA_CENTERとPCA_xt_by_xを一緒に処理\r
+ final long srow = NyMath.sqrtFixdFloat16((long)i_number_of_data<<16);//S16\r
+ long w00, w11, w10;\r
+ w00 = w11 = w10 = 0L;// *out = 0.0;\r
+ for (int i = 0; i < i_number_of_data; i++) {\r
+ final long x = ((i_x[i] - sx)<<16) / srow;//S6\r
+ final long y = ((i_y[i] - sy)<<16) / srow;//S6\r
+ w00 += (x * x)>>16;//S16\r
+ w10 += (x * y)>>16;//S16\r
+ w11 += (y * y)>>16;//S16\r
+ }\r
+ o_matrix.m00=w00;\r
+ o_matrix.m01=o_matrix.m10=w10;\r
+ o_matrix.m11=w11;\r
+ \r
+ //PCA_PCAの処理\r
+ PCA_QRM(o_matrix, o_ev);\r
+ // m2 = o_output.m;// m2 = output->m;\r
+ if (o_ev.x < 0) {// if( ev->v[i] < VZERO ){\r
+ o_ev.x = 0;// ev->v[i] = 0.0;\r
+ o_matrix.m00 = 0;// *(m2++) = 0.0;\r
+ o_matrix.m01 = 0;// *(m2++) = 0.0;\r
+ }\r
+\r
+ if (o_ev.y < 0) {// if( ev->v[i] < VZERO ){\r
+ o_ev.y = 0;// ev->v[i] = 0.0;\r
+ o_matrix.m10 = 0;// *(m2++) = 0.0;\r
+ o_matrix.m11 = 0;// *(m2++) = 0.0;\r
+ }\r
+ o_mean.x=sx;\r
+ o_mean.y=sy;\r
+ // }\r
+ return;\r
+ }\r
+ private int[] __pca_tmpx=null;\r
+ private int[] __pca_tmpy=null;\r
+ private NyARI64Matrix22 __pca_evec=null;\r
+ private NyARI64Point2d __pca_ev=null;\r
+ private NyARI64Point2d __pca_mean=null;\r
+ public void pca(double[] i_x,double[] i_y,int i_number_of_point,NyARDoubleMatrix22 o_evec, NyARDoublePoint2d o_ev,NyARDoublePoint2d o_mean) throws NyARException\r
+ {\r
+ //変換用のワーク変数作成\r
+ if(__pca_tmpx==null)\r
+ {\r
+ this.__pca_tmpx=new int[i_number_of_point];\r
+ this.__pca_tmpy=new int[i_number_of_point];\r
+ this.__pca_evec=new NyARI64Matrix22 ();\r
+ this.__pca_ev=new NyARI64Point2d ();\r
+ this.__pca_mean=new NyARI64Point2d ();\r
+ }else if(i_number_of_point>this.__pca_tmpx.length)\r
+ {\r
+ this.__pca_tmpx=new int[i_number_of_point];\r
+ this.__pca_tmpy=new int[i_number_of_point];\r
+ }\r
+ //値のセット\r
+ final int[] x_ptr=this.__pca_tmpx;\r
+ final int[] y_ptr=this.__pca_tmpy;\r
+ for(int i=0;i<i_number_of_point;i++)\r
+ {\r
+ x_ptr[i]=(int)(i_x[i]*65536L);\r
+ y_ptr[i]=(int)(i_y[i]*65536L);\r
+ }\r
+ //計算\r
+ pcaF16(x_ptr,y_ptr,i_number_of_point,this.__pca_evec,this.__pca_ev,this.__pca_mean);\r
+ //結果値を変換\r
+ o_evec.m00=(double)this.__pca_evec.m00/65536.0;\r
+ o_evec.m01=(double)this.__pca_evec.m01/65536.0;\r
+ o_evec.m10=(double)this.__pca_evec.m10/65536.0;\r
+ o_evec.m11=(double)this.__pca_evec.m11/65536.0;\r
+ o_ev.x=this.__pca_ev.x/65536.0;\r
+ o_ev.y=this.__pca_ev.y/65536.0;\r
+ o_mean.x=this.__pca_mean.x/65536.0;\r
+ o_mean.y=this.__pca_mean.y/65536.0;\r
+ return; \r
+ }\r
+ /**\r
+ * 値は全て小数点部16bitの固定小数点です。\r
+ * @param i_x\r
+ * @param i_y\r
+ * @param i_number_of_point\r
+ * @param o_evec\r
+ * @param o_ev\r
+ * @param o_mean\r
+ * @throws NyARException\r
+ */\r
+ public void pcaF16(int[] i_x,int[] i_y,int i_number_of_point,NyARI64Matrix22 o_evec, NyARI64Point2d o_ev,NyARI64Point2d o_mean) throws NyARException\r
+ {\r
+ //計算\r
+ PCA_PCA(i_x,i_y,i_number_of_point,o_evec,o_ev,o_mean);\r
+ final long sum = o_ev.x + o_ev.y;\r
+ // For順変更禁止\r
+ o_ev.x = (o_ev.x<<16)/sum;// ev->v[i] /= sum;\r
+ o_ev.y = (o_ev.y<<16)/sum;// ev->v[i] /= sum;\r
+ return; \r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARFixedFloat24Matrix33;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point3d;\r
+\r
+\r
+\r
+/**\r
+ * NyARRotMatrix_NyARToolKitのFixedFloat版です。\r
+ * \r
+ */\r
+public class NyARFixedFloatRotMatrix extends NyARFixedFloat24Matrix33\r
+{\r
+ private static int DIV0CANCEL=1;\r
+ /**\r
+ * インスタンスを準備します。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARFixedFloatRotMatrix(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException\r
+ {\r
+ this.__initRot_vec1 = new NyARFixedFloatRotVector(i_matrix);\r
+ this.__initRot_vec2 = new NyARFixedFloatRotVector(i_matrix);\r
+ return;\r
+ }\r
+\r
+ final private NyARFixedFloatRotVector __initRot_vec1;\r
+ final private NyARFixedFloatRotVector __initRot_vec2;\r
+ final private NyARFixedFloat16Point3d _angle=new NyARFixedFloat16Point3d();\r
+\r
+ public final void initRotByPrevResult(NyARTransMatResult i_prev_result)\r
+ {\r
+ this.m00 =(long)(i_prev_result.m00*0x1000000);\r
+ this.m01 =(long)(i_prev_result.m01*0x1000000);\r
+ this.m02 =(long)(i_prev_result.m02*0x1000000);\r
+\r
+ this.m10 =(long)(i_prev_result.m10*0x1000000);\r
+ this.m11 =(long)(i_prev_result.m11*0x1000000);\r
+ this.m12 =(long)(i_prev_result.m12*0x1000000);\r
+\r
+ this.m20 =(long)(i_prev_result.m20*0x1000000);\r
+ this.m21 =(long)(i_prev_result.m21*0x1000000);\r
+ this.m22 =(long)(i_prev_result.m22*0x1000000);\r
+ return;\r
+ }\r
+\r
+ public final void initRotBySquare(final NyARLinear[] i_linear, final NyARFixedFloat16Point2d[] i_sqvertex) throws NyARException\r
+ {\r
+ final NyARFixedFloatRotVector vec1 = this.__initRot_vec1;\r
+ final NyARFixedFloatRotVector vec2 = this.__initRot_vec2;\r
+\r
+ // 向かい合った辺から、2本のベクトルを計算\r
+\r
+ // 軸1\r
+ vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]);\r
+ vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]);\r
+\r
+ // 軸2\r
+ vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]);\r
+ vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]);\r
+\r
+ // 回転の最適化?\r
+ NyARFixedFloatRotVector.checkRotation(vec1, vec2);\r
+ \r
+\r
+ this.m00 = vec1.v1<<8;\r
+ this.m10 = vec1.v2<<8;\r
+ this.m20 = vec1.v3<<8;\r
+ this.m01 = vec2.v1<<8;\r
+ this.m11 = vec2.v2<<8;\r
+ this.m21 = vec2.v3<<8;\r
+ \r
+\r
+\r
+ // 最後の軸を計算\r
+ final long w02 = (vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2)>>16;//S16\r
+ final long w12 = (vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3)>>16;//S16\r
+ final long w22 = (vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1)>>16;//S16\r
+ final long w = NyMath.sqrtFixdFloat((w02 * w02 + w12 * w12 + w22 * w22)>>16,16);//S16\r
+ this.m02 = (w02<<24) / w;\r
+ this.m12 = (w12<<24) / w;\r
+ this.m22 = (w22<<24) / w;\r
+ //Matrixからangleをロード\r
+ this.updateAngleFromMatrix();\r
+ \r
+ return;\r
+ }\r
+ public NyARFixedFloat16Point3d refAngle()\r
+ {\r
+ return this._angle;\r
+ }\r
+ /**\r
+ * int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc ) Optimize:2008.04.20:STEP[481→433] 3x3変換行列から、回転角を復元して返します。\r
+ * \r
+ * @param o_angle\r
+ * @return\r
+ */\r
+ private final void updateAngleFromMatrix()\r
+ {\r
+ int a, b, c;\r
+ long sina, cosa, sinb, cosb, sinc, cosc;\r
+\r
+ if (this.m22 > NyMath.FIXEDFLOAT24_1) {// <Optimize/>if( rot[2][2] > 1.0 ) {\r
+ this.m22 = NyMath.FIXEDFLOAT24_1;// <Optimize/>rot[2][2] = 1.0;\r
+ } else if (this.m22 < -NyMath.FIXEDFLOAT24_1) {// <Optimize/>}else if( rot[2][2] < -1.0 ) {\r
+ this.m22 = -NyMath.FIXEDFLOAT24_1;// <Optimize/>rot[2][2] = -1.0;\r
+ }\r
+ cosb = this.m22;// <Optimize/>cosb = rot[2][2];\r
+ b=NyMath.acosFixedFloat16((int)cosb);\r
+ sinb = (long)NyMath.sinFixedFloat24(b);\r
+ final long rot02 = this.m02;\r
+ final long rot12 = this.m12;\r
+ if (sinb!=0) {\r
+ cosa = (rot02<<24) / sinb;// <Optimize/>cosa = rot[0][2] / sinb;\r
+ sina = (rot12<<24) / sinb;// <Optimize/>sina = rot[1][2] / sinb;\r
+ if (cosa > NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("cos(alph) = %f\n", cosa); */\r
+ cosa = NyMath.FIXEDFLOAT24_1;\r
+ sina = 0;\r
+ }\r
+ if (cosa < -NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("cos(alph) = %f\n", cosa); */\r
+ cosa = -NyMath.FIXEDFLOAT24_1;\r
+ sina = 0;\r
+ }\r
+ if (sina > NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("sin(alph) = %f\n", sina); */\r
+ sina = NyMath.FIXEDFLOAT24_1;\r
+ cosa = 0;\r
+ }\r
+ if (sina < -NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("sin(alph) = %f\n", sina); */\r
+ sina = -NyMath.FIXEDFLOAT24_1;\r
+ cosa = 0;\r
+ }\r
+ a = NyMath.acosFixedFloat16((int)cosa);\r
+ if (sina < 0) {\r
+ a = -a;\r
+ }\r
+ // <Optimize>\r
+ // sinc = (rot[2][1]*rot[0][2]-rot[2][0]*rot[1][2])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);\r
+ // cosc = -(rot[0][2]*rot[2][0]+rot[1][2]*rot[2][1])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]);\r
+ final long tmp = DIV0CANCEL+((rot02 * rot02 + rot12 * rot12)>>24);\r
+ sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp;\r
+ cosc = -(rot02 * this.m20 + rot12 * this.m21) / tmp;\r
+ // </Optimize>\r
+\r
+ if (cosc > NyMath.FIXEDFLOAT24_1){\r
+ /* printf("cos(r) = %f\n", cosc); */\r
+ cosc = NyMath.FIXEDFLOAT24_1;\r
+ sinc = 0;\r
+ }\r
+ if (cosc < -NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("cos(r) = %f\n", cosc); */\r
+ cosc = -NyMath.FIXEDFLOAT24_1;\r
+ sinc = 0;\r
+ }\r
+ if (sinc > NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("sin(r) = %f\n", sinc); */\r
+ sinc = NyMath.FIXEDFLOAT24_1;\r
+ cosc = 0;\r
+ }\r
+ if (sinc < -NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("sin(r) = %f\n", sinc); */\r
+ sinc = -NyMath.FIXEDFLOAT24_1;\r
+ cosc = 0;\r
+ }\r
+ c = (int)NyMath.acosFixedFloat16((int)cosc);\r
+ if (sinc < 0) {\r
+ c = -c;\r
+ }\r
+ } else {\r
+ a = b = 0;\r
+ cosa = cosb = NyMath.FIXEDFLOAT24_1;\r
+ sina = sinb = 0;\r
+ cosc = this.m00;// cosc = rot[0];// <Optimize/>cosc = rot[0][0];\r
+ sinc = this.m01;// sinc = rot[1];// <Optimize/>sinc = rot[1][0];\r
+ if (cosc > NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("cos(r) = %f\n", cosc); */\r
+ cosc = NyMath.FIXEDFLOAT24_1;\r
+ sinc = 0;\r
+ }\r
+ if (cosc < -NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("cos(r) = %f\n", cosc); */\r
+ cosc = -NyMath.FIXEDFLOAT24_1;\r
+ sinc = 0;\r
+ }\r
+ if (sinc > NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("sin(r) = %f\n", sinc); */\r
+ sinc = NyMath.FIXEDFLOAT24_1;\r
+ cosc = 0;\r
+ }\r
+ if (sinc < -NyMath.FIXEDFLOAT24_1) {\r
+ /* printf("sin(r) = %f\n", sinc); */\r
+ sinc = -NyMath.FIXEDFLOAT24_1;\r
+ cosc = 0;\r
+ }\r
+ c = NyMath.acosFixedFloat16((int)cosc);\r
+ if (sinc < 0) {\r
+ c = -c;\r
+ }\r
+ }\r
+ this._angle.x = (long)a;// wa.value=a;//*wa = a;\r
+ this._angle.y = (long)b;// wb.value=b;//*wb = b;\r
+ this._angle.z = (long)c;// wc.value=c;//*wc = c;\r
+ return;\r
+ }\r
+ public final void setAngle(int i_x, int i_y, int i_z)\r
+ {\r
+ /*\r
+ * |cos(a) -sin(a) 0| |cos(b) 0 sin(b)| |cos(a-c) sin(a-c) 0| rot = |sin(a) cos(a) 0| |0 1 0 | |-sin(a-c) cos(a-c) 0| |0 0 1| |-sin(b) 0 cos(b)| |0 0 1|\r
+ */\r
+\r
+ long Sa, Sb, Ca, Cb, Sac, Cac, CaCb, SaCb;\r
+ Sa = NyMath.sinFixedFloat24(i_x);\r
+ Ca = NyMath.cosFixedFloat24(i_x);\r
+ Sb = NyMath.sinFixedFloat24(i_y);\r
+ Cb = NyMath.cosFixedFloat24(i_y);\r
+ Sac = NyMath.sinFixedFloat24(i_x - i_z);\r
+ Cac = NyMath.cosFixedFloat24(i_x - i_z);\r
+ CaCb =(Ca * Cb)>>24;\r
+ SaCb =(Sa * Cb)>>24;\r
+\r
+ this.m00 =(CaCb * Cac + Sa * Sac)>>24;\r
+ this.m01 =(CaCb * Sac - Sa * Cac)>>24;\r
+ this.m02 =(Ca * Sb)>>24;\r
+ this.m10 =(SaCb * Cac - Ca * Sac)>>24;\r
+ this.m11 =(SaCb * Sac + Ca * Cac)>>24;\r
+ this.m12 =(Sa * Sb)>>24;\r
+ this.m20 =(-Sb * Cac)>>24;\r
+ this.m21 =(-Sb * Sac)>>24;\r
+ this.m22 =Cb;\r
+ //angleを逆計算せずに直接代入\r
+ this._angle.x=i_x;\r
+ this._angle.y=i_y;\r
+ this._angle.z=i_z; \r
+ return;\r
+ }\r
+ /**\r
+ * i_in_pointを変換行列で座標変換する。\r
+ * \r
+ * @param i_in_point\r
+ * @param i_out_point\r
+ */\r
+ public final void getPoint3d(final NyARFixedFloat16Point3d i_in_point, final NyARFixedFloat16Point3d i_out_point)\r
+ {\r
+ i_out_point.x = (this.m00 * i_in_point.x + this.m01 * i_in_point.y + this.m02 * i_in_point.z)>>24;\r
+ i_out_point.y = (this.m10 * i_in_point.x + this.m11 * i_in_point.y + this.m12 * i_in_point.z)>>24;\r
+ i_out_point.z = (this.m20 * i_in_point.x + this.m21 * i_in_point.y + this.m22 * i_in_point.z)>>24;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 複数の頂点を一括して変換する\r
+ * \r
+ * @param i_in_point\r
+ * @param i_out_point\r
+ * @param i_number_of_vertex\r
+ */\r
+ public final void getPoint3dBatch(final NyARFixedFloat16Point3d[] i_in_point, NyARFixedFloat16Point3d[] i_out_point, int i_number_of_vertex)\r
+ {\r
+ for (int i = i_number_of_vertex - 1; i >= 0; i--) {\r
+ final NyARFixedFloat16Point3d out_ptr = i_out_point[i];\r
+ final NyARFixedFloat16Point3d in_ptr = i_in_point[i];\r
+ out_ptr.x =(this.m00 * in_ptr.x + this.m01 * in_ptr.y + this.m02 * in_ptr.z)>>24;\r
+ out_ptr.y =(this.m10 * in_ptr.x + this.m11 * in_ptr.y + this.m12 * in_ptr.z)>>24;\r
+ out_ptr.z =(this.m20 * in_ptr.x + this.m21 * in_ptr.y + this.m22 * in_ptr.z)>>24;\r
+ }\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point3d;\r
+\r
+/**\r
+ * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算\r
+ * を繰り返して、変換行列を最適化する。\r
+ *\r
+ */\r
+public class NyARFixedFloatRotTransOptimize_O2\r
+{\r
+ private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 1;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5\r
+ private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+ public NyARFixedFloatRotTransOptimize_O2(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+ {\r
+ this._projection_mat_ref=i_projection_mat_ref;\r
+ return;\r
+ }\r
+ \r
+ final public double optimize(NyARFixedFloatRotMatrix io_rotmat,NyARFixedFloat16Point3d io_transvec,NyARFixedFloatFitVecCalculator i_calculator) throws NyARException\r
+ {\r
+ final NyARFixedFloat16Point2d[] fit_vertex=i_calculator.getFitSquare();\r
+ final NyARFixedFloat16Point3d[] offset_square=i_calculator.getOffsetVertex().vertex;\r
+ \r
+ double err = -1;\r
+ err = modifyMatrix(io_rotmat,io_transvec,offset_square,fit_vertex);\r
+ /*ループを抜けるタイミングをARToolKitと合わせるために変なことしてます。*/\r
+ for (int i = 0; ; i++)\r
+ {\r
+ // <arGetTransMat3>\r
+ err = modifyMatrix(io_rotmat, io_transvec, offset_square, fit_vertex);\r
+ i_calculator.calculateTransfer(io_rotmat, io_transvec);\r
+ err = modifyMatrix(io_rotmat, io_transvec, offset_square, fit_vertex);\r
+ // //</arGetTransMat3>\r
+ if (err < 1.0 || i == AR_GET_TRANS_MAT_MAX_LOOP_COUNT - 1)\r
+ {\r
+ break;\r
+ }\r
+ i_calculator.calculateTransfer(io_rotmat, io_transvec);\r
+ }\r
+ return err;\r
+ }\r
+ \r
+ private final long[][] __modifyMatrix_double1D = new long[8][3];\r
+ private final long INITIAL_FACTOR=(long)(0x10000*5.0 * Math.PI / 180.0);\r
+ /**\r
+ * arGetRot計算を階層化したModifyMatrix 896\r
+ * \r
+ * @param nyrot\r
+ * @param trans\r
+ * @param i_vertex3d\r
+ * [m][3]\r
+ * @param i_vertex2d\r
+ * [n][2]\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ private double modifyMatrix(NyARFixedFloatRotMatrix io_rot,NyARFixedFloat16Point3d trans, NyARFixedFloat16Point3d[] i_vertex3d, NyARFixedFloat16Point2d[] i_vertex2d) throws NyARException\r
+ {\r
+ long a2, b2, c2;\r
+ long h, x, y;\r
+ long err, minerr = 0;\r
+ int t1, t2, t3;\r
+ int best_idx=0;\r
+\r
+ long factor = INITIAL_FACTOR;\r
+ long rot0, rot1, rot2;\r
+ long combo00, combo01, combo02, combo03, combo10, combo11, combo12, combo13, combo20, combo21, combo22, combo23;\r
+ long combo02_2, combo02_5, combo02_8, combo02_11;\r
+ long combo22_2, combo22_5, combo22_8, combo22_11;\r
+ long combo12_2, combo12_5, combo12_8, combo12_11;\r
+ // vertex展開\r
+ final long VX00, VX01, VX02, VX10, VX11, VX12, VX20, VX21, VX22, VX30, VX31, VX32;\r
+ VX00 = i_vertex3d[0].x;\r
+ VX01 = i_vertex3d[0].y;\r
+ VX02 = i_vertex3d[0].z;\r
+ VX10 = i_vertex3d[1].x;\r
+ VX11 = i_vertex3d[1].y;\r
+ VX12 = i_vertex3d[1].z;\r
+ VX20 = i_vertex3d[2].x;\r
+ VX21 = i_vertex3d[2].y;\r
+ VX22 = i_vertex3d[2].z;\r
+ VX30 = i_vertex3d[3].x;\r
+ VX31 = i_vertex3d[3].y;\r
+ VX32 = i_vertex3d[3].z;\r
+ final long P2D00, P2D01, P2D10, P2D11, P2D20, P2D21, P2D30, P2D31;\r
+ P2D00 = i_vertex2d[0].x;\r
+ P2D01 = i_vertex2d[0].y;\r
+ P2D10 = i_vertex2d[1].x;\r
+ P2D11 = i_vertex2d[1].y;\r
+ P2D20 = i_vertex2d[2].x;\r
+ P2D21 = i_vertex2d[2].y;\r
+ P2D30 = i_vertex2d[3].x;\r
+ P2D31 = i_vertex2d[3].y;\r
+ final NyARPerspectiveProjectionMatrix prjmat = this._projection_mat_ref;\r
+ final long CP0,CP1,CP2,CP3,CP4,CP5,CP6,CP7,CP8,CP9,CP10;\r
+ CP0 = (long)(prjmat.m00*0x10000L);\r
+ CP1 = (long)(prjmat.m01*0x10000L);\r
+ CP2 = (long)(prjmat.m02*0x10000L);\r
+ CP4 = (long)(prjmat.m10*0x10000L);\r
+ CP5 = (long)(prjmat.m11*0x10000L);\r
+ CP6 = (long)(prjmat.m12*0x10000L);\r
+ CP8 = (long)(prjmat.m20*0x10000L);\r
+ CP9 = (long)(prjmat.m21*0x10000L);\r
+ CP10 =(long)(prjmat.m22*0x10000L);\r
+\r
+ combo03 = ((CP0 * trans.x + CP1 * trans.y + CP2 * trans.z)>>16) + (long)(prjmat.m03*0x10000L);\r
+ combo13 = ((CP4 * trans.x + CP5 * trans.y + CP6 * trans.z)>>16) + (long)(prjmat.m13*0x10000L);\r
+ combo23 = ((CP8 * trans.x + CP9 * trans.y + CP10 * trans.z)>>16) + (long)(prjmat.m23*0x10000L);\r
+ long CACA, SASA, SACA, CA, SA;\r
+ long CACACB, SACACB, SASACB, CASB, SASB;\r
+ long SACASC, SACACBSC, SACACBCC, SACACC;\r
+ final long[][] double1D = this.__modifyMatrix_double1D;\r
+\r
+ final long[] a_factor = double1D[1];\r
+ final long[] sinb = double1D[2];\r
+ final long[] cosb = double1D[3];\r
+ final long[] b_factor = double1D[4];\r
+ final long[] sinc = double1D[5];\r
+ final long[] cosc = double1D[6];\r
+ final long[] c_factor = double1D[7];\r
+ long w, w2;\r
+ long wsin, wcos;\r
+ \r
+ final NyARFixedFloat16Point3d angle=io_rot.refAngle();// arGetAngle( rot, &a, &b, &c );\r
+ a2 =angle.x;\r
+ b2 =angle.y;\r
+ c2 =angle.z;\r
+\r
+ // comboの3行目を先に計算\r
+ for (int i = 0; i < 10; i++) {\r
+ minerr = 0x4000000000000000L;\r
+ // sin-cosテーブルを計算(これが外に出せるとは…。)\r
+ for (int j = 0; j < 3; j++) {\r
+ w2 = factor * (j - 1);//S16\r
+ w = a2 + w2;//S16\r
+ a_factor[j] = w;//S16\r
+ w = b2 + w2;//S16\r
+ b_factor[j] = w;//S16\r
+ sinb[j] = NyMath.sinFixedFloat24((int)w);\r
+ cosb[j] = NyMath.cosFixedFloat24((int)w);\r
+ w = c2 + w2;//S16\r
+ c_factor[j] = w;//S16\r
+ sinc[j] = NyMath.sinFixedFloat24((int)w);\r
+ cosc[j] = NyMath.cosFixedFloat24((int)w);\r
+ }\r
+ //\r
+ for (t1 = 0; t1 < 3; t1++) {\r
+ SA = NyMath.sinFixedFloat24((int)a_factor[t1]);\r
+ CA = NyMath.cosFixedFloat24((int)a_factor[t1]);\r
+ // Optimize\r
+ CACA = (CA * CA)>>24;//S24\r
+ SASA = (SA * SA)>>24;//S24\r
+ SACA = (SA * CA)>>24;//S24\r
+ for (t2 = 0; t2 < 3; t2++) {\r
+ wsin = sinb[t2];//S24\r
+ wcos = cosb[t2];//S24\r
+ CACACB = (CACA * wcos)>>24;//S24\r
+ SACACB = (SACA * wcos)>>24;//S24\r
+ SASACB = (SASA * wcos)>>24;//S24\r
+ CASB = (CA * wsin)>>24;//S24\r
+ SASB = (SA * wsin)>>24;//S24\r
+\r
+ // comboの計算1\r
+ combo02 = (CP0 * CASB + CP1 * SASB + CP2 * wcos)>>24;//S24*S16>>24=S16\r
+ combo12 = (CP4 * CASB + CP5 * SASB + CP6 * wcos)>>24;//S24*S16>>24=S16\r
+ combo22 = (CP8 * CASB + CP9 * SASB + CP10 * wcos)>>24;//S24*S16>>24=S16\r
+\r
+ combo02_2 = ((combo02 * VX02)>>16) + combo03;//S16\r
+ combo02_5 = ((combo02 * VX12)>>16) + combo03;//S16\r
+ combo02_8 = ((combo02 * VX22)>>16) + combo03;//S16\r
+ combo02_11 = ((combo02 * VX32)>>16) + combo03;//S16\r
+ combo12_2 = ((combo12 * VX02)>>16) + combo13;//S16\r
+ combo12_5 = ((combo12 * VX12)>>16) + combo13;//S16\r
+ combo12_8 = ((combo12 * VX22)>>16) + combo13;//S16\r
+ combo12_11 = ((combo12 * VX32)>>16) + combo13;//S16\r
+ combo22_2 = ((combo22 * VX02)>>16) + combo23;//S16\r
+ combo22_5 = ((combo22 * VX12)>>16) + combo23;//S16\r
+ combo22_8 = ((combo22 * VX22)>>16) + combo23;//S16\r
+ combo22_11 = ((combo22 * VX32)>>16) + combo23;//S16\r
+ for (t3 = 0; t3 < 3; t3++) {\r
+ wsin = sinc[t3];//S24\r
+ wcos = cosc[t3];//S24\r
+ SACASC = (SACA * wsin)>>24;//S24\r
+ SACACC = (SACA * wcos)>>24;//S24\r
+ SACACBSC =(SACACB * wsin)>>24;//S24;\r
+ SACACBCC = (SACACB * wcos)>>24;//S24;\r
+\r
+ rot0 = ((CACACB * wcos + SASA * wcos)>>24) + SACACBSC - SACASC;//S24;\r
+ rot1 = SACACBCC - SACACC + ((SASACB * wsin + CACA * wsin)>>24);//S24;\r
+ rot2 = (-CASB * wcos - SASB * wsin)>>24;//S24;\r
+ combo00 = (CP0 * rot0 + CP1 * rot1 + CP2 * rot2)>>24;//S16\r
+ combo10 = (CP4 * rot0 + CP5 * rot1 + CP6 * rot2)>>24;//S16\r
+ combo20 = (CP8 * rot0 + CP9 * rot1 + CP10 * rot2)>>24;//S16\r
+\r
+ rot0 = ((-CACACB * wsin - SASA * wsin)>>24) + SACACBCC - SACACC;//S24\r
+ rot1 = -SACACBSC + SACASC + ((SASACB * wcos + CACA * wcos)>>24);//S24\r
+ rot2 = (CASB * wsin - SASB * wcos)>>24;//S24\r
+\r
+ combo01 =(CP0 * rot0 + CP1 * rot1 + CP2 * rot2)>>24;//S16\r
+ combo11 =(CP4 * rot0 + CP5 * rot1 + CP6 * rot2)>>24;//S16\r
+ combo21 =(CP8 * rot0 + CP9 * rot1 + CP10 * rot2)>>24;//S16\r
+ //\r
+ err =0;\r
+ h = ((combo20 * VX00 + combo21 * VX01)>>16) + combo22_2;//S16\r
+ x = P2D00 - ((((combo00 * VX00 + combo01 * VX01)>>16) + combo02_2)<<16) / h;//S16\r
+ y = P2D01 - ((((combo10 * VX00 + combo11 * VX01)>>16) + combo12_2)<<16) / h;//S16\r
+ err += ((x * x + y * y)>>16);\r
+ h = ((combo20 * VX10 + combo21 * VX11)>>16) + combo22_5;\r
+ x = P2D10 - ((((combo00 * VX10 + combo01 * VX11)>>16) + combo02_5)<<16) / h;//S16\r
+ y = P2D11 - ((((combo10 * VX10 + combo11 * VX11)>>16) + combo12_5)<<16) / h;//S16\r
+ err += ((x * x + y * y)>>16);\r
+ h = ((combo20 * VX20 + combo21 * VX21)>>16) + combo22_8;\r
+ x = P2D20 - ((((combo00 * VX20 + combo01 * VX21)>>16) + combo02_8)<<16) / h;//S16\r
+ y = P2D21 - ((((combo10 * VX20 + combo11 * VX21)>>16) + combo12_8)<<16) / h;//S16\r
+ err += ((x * x + y * y)>>16);\r
+ h = ((combo20 * VX30 + combo21 * VX31)>>16) + combo22_11;\r
+ x = P2D30 - ((((combo00 * VX30 + combo01 * VX31)>>16) + combo02_11)<<16) / h;//S16\r
+ y = P2D31 - ((((combo10 * VX30 + combo11 * VX31)>>16) + combo12_11)<<16) / h;//S16\r
+ err += ((x * x + y * y)>>16);\r
+ if (err < minerr) {\r
+ minerr = err;\r
+ a2 = a_factor[t1];\r
+ b2 = b_factor[t2];\r
+ c2 = c_factor[t3];\r
+ best_idx=t1+t2*3+t3*9;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (best_idx==(1+3+9)) {\r
+ factor=factor>>1;\r
+ }\r
+ }\r
+ io_rot.setAngle((int)a2,(int)b2,(int)c2);\r
+ /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
+ return minerr /4;//この設定値おかしくね?16bitfixedfloatなら16で割らないと。\r
+ } \r
+ \r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARFixedFloat16Matrix33;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point2d;\r
+\r
+public class NyARFixedFloatRotVector\r
+{\r
+ //publicメンバ達\r
+ public long v1;\r
+\r
+ public long v2;\r
+\r
+ public long v3;\r
+\r
+ //privateメンバ達\r
+ private NyARFixedFloat16Matrix33 _cmat = new NyARFixedFloat16Matrix33();\r
+\r
+ private NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+\r
+ private double[][] _inv_cpara_array_ref;\r
+\r
+ public NyARFixedFloatRotVector(NyARPerspectiveProjectionMatrix i_cmat) throws NyARException\r
+ {\r
+ final NyARMat mat_a = new NyARMat(3, 3);\r
+ final double[][] a_array = mat_a.getArray();\r
+\r
+ a_array[0][0] = i_cmat.m00;\r
+ a_array[0][1] = i_cmat.m01;\r
+ a_array[0][2] = i_cmat.m02;\r
+ a_array[1][0] = i_cmat.m10;\r
+ a_array[1][1] = i_cmat.m11;\r
+ a_array[1][2] = i_cmat.m12;\r
+ a_array[2][0] = i_cmat.m20;\r
+ a_array[2][1] = i_cmat.m21;\r
+ a_array[2][2] = i_cmat.m22;\r
+\r
+ mat_a.matrixSelfInv();\r
+ this._projection_mat_ref = i_cmat;\r
+ //FixedFloat16にコピー\r
+ this._cmat.m00 = (long)(i_cmat.m00 * NyMath.FIXEDFLOAT24_1);\r
+ this._cmat.m01 = (long)(i_cmat.m01 * NyMath.FIXEDFLOAT24_1);\r
+ this._cmat.m02 = (long)(i_cmat.m02 * NyMath.FIXEDFLOAT24_1);\r
+ this._cmat.m10 = (long)(i_cmat.m10 * NyMath.FIXEDFLOAT24_1);\r
+ this._cmat.m11 = (long)(i_cmat.m11 * NyMath.FIXEDFLOAT24_1);\r
+ this._cmat.m12 = (long)(i_cmat.m12 * NyMath.FIXEDFLOAT24_1);\r
+ this._cmat.m20 = (long)(i_cmat.m20 * NyMath.FIXEDFLOAT24_1);\r
+ this._cmat.m21 = (long)(i_cmat.m21 * NyMath.FIXEDFLOAT24_1);\r
+ this._cmat.m22 = (long)(i_cmat.m22 * NyMath.FIXEDFLOAT24_1);\r
+ this._inv_cpara_array_ref = mat_a.getArray();\r
+ //GCない言語のときは、ここで配列の所有権委譲してね!\r
+ }\r
+\r
+ /**\r
+ * 2直線に直交するベクトルを計算する・・・だと思う。\r
+ * @param i_linear1\r
+ * @param i_linear2\r
+ */\r
+ public void exteriorProductFromLinear(NyARLinear i_linear1, NyARLinear i_linear2)\r
+ {\r
+ //1行目\r
+ NyARPerspectiveProjectionMatrix cmat = this._projection_mat_ref;\r
+ final double w1 = i_linear1.dy * i_linear2.dx - i_linear2.dy * i_linear1.dx;\r
+ final double w2 = i_linear1.dx * i_linear2.c - i_linear2.dx * i_linear1.c;\r
+ final double w3 = i_linear1.c * i_linear2.dy - i_linear2.c * i_linear1.dy;\r
+\r
+ final double m0 = w1 * (cmat.m01 * cmat.m12 - cmat.m02 * cmat.m11) + w2 * cmat.m11 - w3 * cmat.m01;//w1 * (cpara[0 * 4 + 1] * cpara[1 * 4 + 2] - cpara[0 * 4 + 2] * cpara[1 * 4 + 1]) + w2 * cpara[1 * 4 + 1] - w3 * cpara[0 * 4 + 1];\r
+ final double m1 = -w1 * cmat.m00 * cmat.m12 + w3 * cmat.m00;//-w1 * cpara[0 * 4 + 0] * cpara[1 * 4 + 2] + w3 * cpara[0 * 4 + 0];\r
+ final double m2 = w1 * cmat.m00 * cmat.m11;//w1 * cpara[0 * 4 + 0] * cpara[1 * 4 + 1];\r
+ final double w = Math.sqrt(m0 * m0 + m1 * m1 + m2 * m2);\r
+ this.v1 = (long)(m0 * NyMath.FIXEDFLOAT16_1 / w);\r
+ this.v2 = (long)(m1 * NyMath.FIXEDFLOAT16_1 / w);\r
+ this.v3 = (long)(m2 * NyMath.FIXEDFLOAT16_1 / w);\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * static int check_dir( double dir[3], double st[2], double ed[2],double cpara[3][4] ) Optimize:STEP[526->468]\r
+ * ベクトルの開始/終了座標を指定して、ベクトルの方向を調整する。\r
+ * @param i_start_vertex\r
+ * @param i_end_vertex\r
+ * @param cpara\r
+ */\r
+ public void checkVectorByVertex(NyARFixedFloat16Point2d i_start_vertex, NyARFixedFloat16Point2d i_end_vertex) throws NyARException\r
+ {\r
+ long h;\r
+ final double[][] inv_cpara = this._inv_cpara_array_ref;\r
+ final double stx = (double)(i_start_vertex.x / NyMath.FIXEDFLOAT16_1);\r
+ final double sty = (double)(i_start_vertex.y / NyMath.FIXEDFLOAT16_1);\r
+\r
+ //final double[] world = __checkVectorByVertex_world;// [2][3];\r
+ final long world0 = (long)((inv_cpara[0][0] * stx + inv_cpara[0][1] * sty + inv_cpara[0][2]) * 10.0 * NyMath.FIXEDFLOAT16_1);// mat_a->m[0]*st[0]*10.0+\r
+ final long world1 = (long)((inv_cpara[1][0] * stx + inv_cpara[1][1] * sty + inv_cpara[1][2]) * 10.0 * NyMath.FIXEDFLOAT16_1);// mat_a->m[3]*st[0]*10.0+\r
+ final long world2 = (long)((inv_cpara[2][0] * stx + inv_cpara[2][1] * sty + inv_cpara[2][2]) * 10.0 * NyMath.FIXEDFLOAT16_1);// mat_a->m[6]*st[0]*10.0+\r
+ final long world3 = world0 + (this.v1);\r
+ final long world4 = world1 + (this.v2);\r
+ final long world5 = world2 + (this.v3);\r
+ // </Optimize>\r
+\r
+ //final double[] camera = __checkVectorByVertex_camera;// [2][2];\r
+ //h = cpara[2 * 4 + 0] * world0 + cpara[2 * 4 + 1] * world1 + cpara[2 * 4 + 2] * world2;\r
+ h = (this._cmat.m20 * world0 + this._cmat.m21 * world1 + this._cmat.m22 * world2) >> 16;\r
+ if (h == 0)\r
+ {\r
+ throw new NyARException();\r
+ }\r
+ //final double camera0 = (cpara[0 * 4 + 0] * world0 + cpara[0 * 4 + 1] * world1 + cpara[0 * 4 + 2] * world2) / h;\r
+ //final double camera1 = (cpara[1 * 4 + 0] * world0 + cpara[1 * 4 + 1] * world1 + cpara[1 * 4 + 2] * world2) / h;\r
+ final long camera0 = (this._cmat.m00 * world0 + this._cmat.m01 * world1 + this._cmat.m02 * world2) / h;\r
+ final long camera1 = (this._cmat.m10 * world0 + this._cmat.m11 * world1 + this._cmat.m12 * world2) / h;\r
+\r
+ //h = cpara[2 * 4 + 0] * world3 + cpara[2 * 4 + 1] * world4 + cpara[2 * 4 + 2] * world5;\r
+ h = (this._cmat.m20 * world3 + this._cmat.m21 * world4 + this._cmat.m22 * world5) >> 16;\r
+ if (h == 0)\r
+ {\r
+ throw new NyARException();\r
+ }\r
+ //final double camera2 = (cpara[0 * 4 + 0] * world3 + cpara[0 * 4 + 1] * world4 + cpara[0 * 4 + 2] * world5) / h;\r
+ //final double camera3 = (cpara[1 * 4 + 0] * world3 + cpara[1 * 4 + 1] * world4 + cpara[1 * 4 + 2] * world5) / h;\r
+ final long camera2 = (this._cmat.m00 * world3 + this._cmat.m01 * world4 + this._cmat.m02 * world5) / h;\r
+ final long camera3 = (this._cmat.m10 * world3 + this._cmat.m11 * world4 + this._cmat.m12 * world5) / h;\r
+\r
+\r
+ long v = ((i_end_vertex.x - i_start_vertex.x) * (camera2 - camera0) + (i_end_vertex.y - i_start_vertex.y) * (camera3 - camera1)) >> 16;\r
+\r
+ if (v < 0)\r
+ {\r
+ this.v1 = -this.v1;\r
+ this.v2 = -this.v2;\r
+ this.v3 = -this.v3;\r
+ }\r
+\r
+ return;\r
+ }\r
+ private static int DIV0_CANCEL=1;\r
+ /**\r
+ * int check_rotation( double rot[2][3] )\r
+ * 2つのベクトル引数の調整をする?\r
+ * @param i_r\r
+ * @throws NyARException\r
+ */\r
+ public final static void checkRotation(NyARFixedFloatRotVector io_vec1, NyARFixedFloatRotVector io_vec2) throws NyARException\r
+ {\r
+ long w;\r
+ int f;\r
+\r
+ long vec10 = io_vec1.v1;\r
+ long vec11 = io_vec1.v2;\r
+ long vec12 = io_vec1.v3;\r
+ long vec20 = io_vec2.v1;\r
+ long vec21 = io_vec2.v2;\r
+ long vec22 = io_vec2.v3;\r
+ \r
+ long vec30 = (vec11 * vec22 - vec12 * vec21)>>16;\r
+ long vec31 = (vec12 * vec20 - vec10 * vec22)>>16;\r
+ long vec32 = (vec10 * vec21 - vec11 * vec20)>>16;\r
+ w = NyMath.sqrtFixdFloat16((vec30 * vec30 + vec31 * vec31 + vec32 * vec32)>>16);\r
+ if (w == 0) {\r
+ w=1;//極小値\r
+ //throw new NyARException();\r
+ }\r
+ vec30= (vec30<<16)/w;\r
+ vec31= (vec31<<16)/w;\r
+ vec32= (vec32<<16)/w;\r
+\r
+ long cb = (vec10 * vec20 + vec11 * vec21 + vec12 * vec22)>>16;\r
+ if (cb < 0){\r
+ cb=-cb;//cb *= -1.0; \r
+ }\r
+ final long ca = (NyMath.sqrtFixdFloat16(cb + NyMath.FIXEDFLOAT16_1) + NyMath.sqrtFixdFloat16(NyMath.FIXEDFLOAT16_1 - cb)) >>1;\r
+\r
+ if (vec31 * vec10 - vec11 * vec30 != 0) {\r
+ f = 0;\r
+ } else {\r
+ if (vec32 * vec10 - vec12 * vec30 != 0) {\r
+ w = vec11;vec11 = vec12;vec12 = w;\r
+ w = vec31;vec31 = vec32;vec32 = w;\r
+ f = 1;\r
+ } else {\r
+ w = vec10;vec10 = vec12;vec12 = w;\r
+ w = vec30;vec30 = vec32;vec32 = w;\r
+ f = 2;\r
+ }\r
+ }\r
+ if (vec31 * vec10 - vec11 * vec30 == 0) {\r
+ throw new NyARException();\r
+ }\r
+ \r
+ long k1,k2,k3,k4;\r
+ long a, b, c, d;\r
+ long p1, q1, r1;\r
+ long p2, q2, r2;\r
+ long p3, q3, r3;\r
+ long p4, q4, r4; \r
+ \r
+ \r
+ k1 = ((vec11 * vec32 - vec31 * vec12)) / (DIV0_CANCEL+((vec31 * vec10 - vec11 * vec30)>>16));\r
+ k2 = (vec31 * ca) / (DIV0_CANCEL+((vec31 * vec10 - vec11 * vec30)>>16));\r
+ k3 = (vec10 * vec32 - vec30 * vec12) / (DIV0_CANCEL+((vec30 * vec11 - vec10 * vec31)>>16));\r
+ k4 = (vec30 * ca) / (DIV0_CANCEL+((vec30 * vec11 - vec10 * vec31)>>16));\r
+\r
+ a = ((k1 * k1 + k3 * k3)>>16) + NyMath.FIXEDFLOAT16_1;\r
+ b = ((k1 * k2 + k3 * k4)>>16);\r
+ c = ((k2 * k2 + k4 * k4)>>16) - NyMath.FIXEDFLOAT16_1;\r
+ d = (b*b - a*c)>>16;\r
+ if (d < 0) {\r
+ //誤差で計算エラーが頻発するのでExceptionはしない\r
+ //throw new NyARException();\r
+ }\r
+ r1 = ((-b + NyMath.sqrtFixdFloat16(d))<<16) / a;\r
+ p1 = ((k1 * r1)>>16) + k2;\r
+ q1 = ((k3 * r1)>>16) + k4;\r
+ r2 = ((-b - NyMath.sqrtFixdFloat16(d))<<16) / a;\r
+ p2 = ((k1 * r2)>>16) + k2;\r
+ q2 = ((k3 * r2)>>16) + k4;\r
+ if (f == 1) {\r
+ w = q1;q1 = r1;r1 = w;\r
+ w = q2;q2 = r2;r2 = w;\r
+ w = vec11;vec11 = vec12;vec12 = w;\r
+ w = vec31;vec31 = vec32;vec32 = w;\r
+ f = 0;\r
+ }\r
+ if (f == 2) {\r
+ w = p1;p1 = r1;r1 = w;\r
+ w = p2;p2 = r2;r2 = w;\r
+ w = vec10;vec10 = vec12;vec12 = w;\r
+ w = vec30;vec30 = vec32;vec32 = w;\r
+ f = 0;\r
+ }\r
+\r
+ if (vec31 * vec20 - vec21 * vec30 != 0) {\r
+ f = 0;\r
+ } else {\r
+ if (vec32 * vec20 - vec22 * vec30 != 0) {\r
+ w = vec21;vec21 = vec22;vec22 = w;\r
+ w = vec31;vec31 = vec32;vec32 = w;\r
+ f = 1;\r
+ } else {\r
+ w = vec20;vec20 = vec22;vec22 = w;\r
+ w = vec30;vec30 = vec32;vec32 = w;\r
+ f = 2;\r
+ }\r
+ }\r
+ if (vec31 * vec20 - vec21 * vec30 == 0) {\r
+ throw new NyARException();\r
+ }\r
+ k1 = (vec21 * vec32 - vec31 * vec22) / (DIV0_CANCEL+((vec31 * vec20 - vec21 * vec30)>>16));\r
+ k2 = (vec31 * ca) / (DIV0_CANCEL+((vec31 * vec20 - vec21 * vec30)>>16));\r
+ k3 = (vec20 * vec32 - vec30 * vec22) / ((vec30 * vec21 - vec20 * vec31)>>16);\r
+ k4 = (vec30 * ca) / (DIV0_CANCEL+((vec30 * vec21 - vec20 * vec31)>>16));\r
+\r
+ a = ((k1 * k1 + k3 * k3)>>16) + NyMath.FIXEDFLOAT16_1;\r
+ b = ((k1 * k2 + k3 * k4)>>16);\r
+ c = ((k2 * k2 + k4 * k4)>>16) - NyMath.FIXEDFLOAT16_1;\r
+\r
+ d = (b*b - a*c)>>16;\r
+ if (d < 0) {\r
+ //誤差で計算エラーが頻発するのでExceptionはしない\r
+// throw new NyARException();\r
+ }\r
+ r3 = ((-b + NyMath.sqrtFixdFloat16(d))<<16) / a;\r
+ p3 = ((k1 * r3)>>16) + k2;\r
+ q3 = ((k3 * r3)>>16) + k4;\r
+ r4 = ((-b - NyMath.sqrtFixdFloat16(d))<<16) / a;\r
+ p4 = ((k1 * r4)>>16) + k2;\r
+ q4 = ((k3 * r4)>>16) + k4;\r
+ if (f == 1) {\r
+ w = q3;q3 = r3;r3 = w;\r
+ w = q4;q4 = r4;r4 = w;\r
+ w = vec21;vec21 = vec22;vec22 = w;\r
+ w = vec31;vec31 = vec32;vec32 = w;\r
+ f = 0;\r
+ }\r
+ if (f == 2) {\r
+ w = p3;p3 = r3;r3 = w;\r
+ w = p4;p4 = r4;r4 = w;\r
+ w = vec20;vec20 = vec22;vec22 = w;\r
+ w = vec30;vec30 = vec32;vec32 = w;\r
+ f = 0;\r
+ }\r
+\r
+ long e1 = (p1 * p3 + q1 * q3 + r1 * r3)>>16;\r
+ if (e1 < 0) {\r
+ e1 = -e1;\r
+ }\r
+ long e2 = (p1 * p4 + q1 * q4 + r1 * r4)>>16;\r
+ if (e2 < 0) {\r
+ e2 = -e2;\r
+ }\r
+ long e3 = (p2 * p3 + q2 * q3 + r2 * r3)>>16;\r
+ if (e3 < 0) {\r
+ e3 = -e3;\r
+ }\r
+ long e4 = (p2 * p4 + q2 * q4 + r2 * r4)>>16;\r
+ if (e4 < 0) {\r
+ e4 = -e4;\r
+ }\r
+ if (e1 < e2) {\r
+ if (e1 < e3) {\r
+ if (e1 < e4) {\r
+ io_vec1.v1 = p1;\r
+ io_vec1.v2 = q1;\r
+ io_vec1.v3 = r1;\r
+ io_vec2.v1 = p3;\r
+ io_vec2.v2 = q3;\r
+ io_vec2.v3 = r3;\r
+ } else {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p4;\r
+ io_vec2.v2 = q4;\r
+ io_vec2.v3 = r4;\r
+ }\r
+ } else {\r
+ if (e3 < e4) {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p3;\r
+ io_vec2.v2 = q3;\r
+ io_vec2.v3 = r3;\r
+ } else {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p4;\r
+ io_vec2.v2 = q4;\r
+ io_vec2.v3 = r4;\r
+ }\r
+ }\r
+ } else {\r
+ if (e2 < e3) {\r
+ if (e2 < e4) {\r
+ io_vec1.v1 = p1;\r
+ io_vec1.v2 = q1;\r
+ io_vec1.v3 = r1;\r
+ io_vec2.v1 = p4;\r
+ io_vec2.v2 = q4;\r
+ io_vec2.v3 = r4;\r
+ } else {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p4;\r
+ io_vec2.v2 = q4;\r
+ io_vec2.v3 = r4;\r
+ }\r
+ } else {\r
+ if (e3 < e4) {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p3;\r
+ io_vec2.v2 = q3;\r
+ io_vec2.v3 = r3;\r
+ } else {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p4;\r
+ io_vec2.v2 = q4;\r
+ io_vec2.v3 = r4;\r
+ }\r
+ }\r
+ } \r
+ return;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point3d;\r
+\r
+\r
+final public class NyARFixedFloatTransOffset\r
+{\r
+ public NyARFixedFloat16Point3d[] vertex=NyARFixedFloat16Point3d.createArray(4);\r
+ public NyARFixedFloat16Point3d point=new NyARFixedFloat16Point3d(); \r
+ /**\r
+ * 中心位置と辺長から、オフセット情報を作成して設定する。\r
+ * @param i_width\r
+ * FF16で渡すこと!\r
+ * @param i_center\r
+ */\r
+ public void setSquare(long i_width,NyARFixedFloat16Point2d i_center)\r
+ {\r
+ final long w_2 = i_width>>1;\r
+ \r
+ NyARFixedFloat16Point3d vertex3d_ptr;\r
+ vertex3d_ptr= this.vertex[0];\r
+ vertex3d_ptr.x = -w_2;\r
+ vertex3d_ptr.y = w_2;\r
+ vertex3d_ptr.z = 0;\r
+ vertex3d_ptr= this.vertex[1];\r
+ vertex3d_ptr.x = w_2;\r
+ vertex3d_ptr.y = w_2;\r
+ vertex3d_ptr.z = 0;\r
+ vertex3d_ptr= this.vertex[2];\r
+ vertex3d_ptr.x = w_2;\r
+ vertex3d_ptr.y = -w_2;\r
+ vertex3d_ptr.z = 0;\r
+ vertex3d_ptr= this.vertex[3];\r
+ vertex3d_ptr.x = -w_2;\r
+ vertex3d_ptr.y = -w_2;\r
+ vertex3d_ptr.z = 0;\r
+ \r
+ this.point.x=-i_center.x;\r
+ this.point.y=-i_center.y;\r
+ this.point.z=0;\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+public final class NyARFixedFloatVertexCounter\r
+{\r
+ public final int[] vertex = new int[6];// 5まで削れる\r
+\r
+ public int number_of_vertex;\r
+\r
+ private long thresh_16f;\r
+\r
+ private int[] x_coord;\r
+\r
+ private int[] y_coord;\r
+\r
+ public boolean getVertex(int[] i_x_coord, int[] i_y_coord, int st, int ed, long i_thresh)\r
+ {\r
+ this.number_of_vertex = 0;\r
+ this.thresh_16f = i_thresh;\r
+ this.x_coord = i_x_coord;\r
+ this.y_coord = i_y_coord;\r
+ return get_vertex(st, ed);\r
+ }\r
+\r
+ /**\r
+ * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数\r
+ * \r
+ * @param x_coord\r
+ * @param y_coord\r
+ * @param st\r
+ * @param ed\r
+ * @param thresh\r
+ * @return\r
+ */\r
+ private boolean get_vertex(int st, int ed)\r
+ {\r
+ int v1 = 0;\r
+ final int[] lx_coord = this.x_coord;\r
+ final int[] ly_coord = this.y_coord;\r
+ final int a = ly_coord[ed] - ly_coord[st];\r
+ final int b = lx_coord[st] - lx_coord[ed];\r
+ final int c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];\r
+ long dmax = 0;\r
+ for (int i = st + 1; i < ed; i++) {\r
+ final long d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+ if (d * d > dmax) {\r
+ dmax = d * d;\r
+ v1 = i;\r
+ }\r
+ }\r
+ if ((dmax<<16) / (long)(a * a + b * b) > this.thresh_16f) {\r
+ if (!get_vertex(st, v1)) {\r
+ return false;\r
+ }\r
+ if (number_of_vertex > 5) {\r
+ return false;\r
+ }\r
+ vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;\r
+ number_of_vertex++;// (*vnum)++;\r
+\r
+ if (!get_vertex(v1, ed)) {\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilterBuilder_RgbToBin;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilter_ARToolkitThreshold;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;\r
+\r
+\r
+/**\r
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。\r
+ * \r
+ */\r
+public class NyARSingleDetectMarker_X2\r
+{\r
+ private static final int AR_SQUARE_MAX = 100;\r
+\r
+ private boolean _is_continue = false;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;\r
+ private INyARSquareContourDetector _square_detect;\r
+\r
+ private final NyARSquareStack _square_list = new NyARSquareStack(AR_SQUARE_MAX);\r
+\r
+ protected INyARTransMat _transmat;\r
+\r
+ private double _marker_width;\r
+\r
+ // 検出結果の保存用\r
+ private int _detected_direction;\r
+\r
+ private double _detected_confidence;\r
+\r
+ private NyARSquare _detected_square;\r
+\r
+ private INyARColorPatt _patt;\r
+\r
+ /**\r
+ * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。\r
+ * \r
+ * @param i_param\r
+ * カメラパラメータを指定します。\r
+ * @param i_code\r
+ * 検出するARCodeを指定します。\r
+ * @param i_marker_width\r
+ * ARコードの物理サイズを、ミリメートルで指定します。\r
+ * @throws NyARException\r
+ */\r
+ public NyARSingleDetectMarker_X2(NyARParam i_param, NyARCode i_code, double i_marker_width,int i_raster_type) throws NyARException\r
+ {\r
+ final NyARIntSize scr_size=i_param.getScreenSize(); \r
+ // 解析オブジェクトを作る\r
+ this._square_detect = new NyARSquareDetector_X2(i_param.getDistortionFactor(),scr_size);\r
+ this._transmat = new NyARTransMat_X2(i_param);\r
+ this._marker_width = i_marker_width;\r
+ int cw=i_code.getWidth();\r
+ int ch=i_code.getHeight();\r
+ // 評価パターンのホルダを作る\r
+ this._patt = new NyARColorPatt_O3(cw,ch);\r
+ // 評価器を作る。\r
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA(i_code);\r
+ //2値画像バッファを作る\r
+ this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
+ //差分データインスタンスの作成\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(cw,ch);\r
+ this._tobin_filter=new NyARRasterFilterBuilder_RgbToBin(100,i_raster_type);\r
+ return;\r
+ }\r
+\r
+ private NyARBinRaster _bin_raster;\r
+ private NyARRasterFilter_ARToolkitThreshold _tobin_filter;\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+\r
+ \r
+ /**\r
+ * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+ * \r
+ * @param i_raster\r
+ * マーカーを検出するイメージを指定します。イメージサイズは、カメラパラメータ\r
+ * と一致していなければなりません。\r
+ * @return マーカーが検出できたかを真偽値で返します。\r
+ * @throws NyARException\r
+ */\r
+ public boolean detectMarkerLite(INyARRgbRaster i_raster,int i_threshold) throws NyARException\r
+ {\r
+ //サイズチェック\r
+ if(!this._bin_raster.getSize().isEqualSize(i_raster.getSize())){\r
+ throw new NyARException();\r
+ }\r
+\r
+ //ラスタを(1/4の画像の)2値イメージに変換する.\r
+ this._tobin_filter.setThreshold(i_threshold);\r
+ this._tobin_filter.doFilter(i_raster,this._bin_raster);\r
+ \r
+ \r
+ this._detected_square = null;\r
+ NyARSquareStack l_square_list = this._square_list;\r
+ // スクエアコードを探す\r
+ this._square_detect.detectMarkerCB(this._bin_raster, l_square_list);\r
+\r
+\r
+ int number_of_square = l_square_list.getLength();\r
+ // コードは見つかった?\r
+ if (number_of_square < 1) {\r
+ return false;\r
+ }\r
+ boolean result=false;\r
+ NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+ int square_index = 0;\r
+ int direction = NyARSquare.DIRECTION_UNKNOWN;\r
+ double confidence = 0;\r
+ for(int i=0;i<number_of_square;i++){\r
+ // 評価基準になるパターンをイメージから切り出す\r
+ if (!this._patt.pickFromRaster(i_raster, l_square_list.getItem(i).imvertex)){\r
+ continue;\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._patt);\r
+ this._match_patt.evaluate(this._deviation_data,mr);\r
+\r
+ final double c2 = mr.confidence;\r
+ if (confidence > c2) {\r
+ continue;\r
+ }\r
+ // もっと一致するマーカーがあったぽい\r
+ square_index = i;\r
+ direction = mr.direction;\r
+ confidence = c2;\r
+ result=true;\r
+ }\r
+ \r
+ // マーカー情報を保存\r
+ this._detected_square = (NyARSquare)l_square_list.getItem(square_index);\r
+ this._detected_direction = direction;\r
+ this._detected_confidence = confidence;\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。\r
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。\r
+ * \r
+ * @param o_result\r
+ * 変換行列を受け取るオブジェクトを指定します。\r
+ * @throws NyARException\r
+ */\r
+ public void getTransmationMatrix(NyARTransMatResult o_result) throws NyARException\r
+ {\r
+ // 一番一致したマーカーの位置とかその辺を計算\r
+ if (this._is_continue) {\r
+ this._transmat.transMatContinue(this._detected_square,this._detected_direction,this._marker_width, o_result);\r
+ } else {\r
+ this._transmat.transMat(this._detected_square,this._detected_direction,this._marker_width, o_result);\r
+ }\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 検出したマーカーの一致度を返します。\r
+ * \r
+ * @return マーカーの一致度を返します。0~1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。\r
+ * @throws NyARException\r
+ */\r
+ public double getConfidence()\r
+ {\r
+ return this._detected_confidence;\r
+ }\r
+\r
+ /**\r
+ * 検出したマーカーの方位を返します。\r
+ * \r
+ * @return 0,1,2,3の何れかを返します。\r
+ */\r
+ public int getDirection()\r
+ {\r
+ return this._detected_direction;\r
+ }\r
+\r
+ /**\r
+ * getTransmationMatrixの計算モードを設定します。 初期値はTRUEです。\r
+ * \r
+ * @param i_is_continue\r
+ * TRUEなら、transMatCont互換の計算をします。 FALSEなら、transMat互換の計算をします。\r
+ */\r
+ public void setContinueMode(boolean i_is_continue)\r
+ {\r
+ this._is_continue = i_is_continue;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.*;\r
+import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+\r
+\r
+\r
+/**\r
+ * イメージから正方形候補を検出するクラス。\r
+ * このクラスは、arDetectMarker2.cとの置き換えになります。\r
+ * \r
+ */\r
+public class NyARSquareDetector_X2 implements INyARSquareContourDetector\r
+{\r
+ private final int _width;\r
+ private final int _height;\r
+\r
+ private final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> _overlap_checker = new LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo>(32,RleLabelFragmentInfoStack.RleLabelFragmentInfo.class);\r
+ private final SquareContourDetector_X2 _sqconvertor;\r
+ private final ContourPickup _cpickup=new ContourPickup();\r
+ private final RleLabelFragmentInfoStack _stack;\r
+\r
+ \r
+ \r
+ private final NyARLabeling_Rle _labeling;\r
+ /**\r
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARSquareDetector_X2(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
+ {\r
+ this._width = i_size.w;\r
+ this._height = i_size.h;\r
+ this._labeling = new NyARLabeling_Rle(this._width,this._height);\r
+ this._sqconvertor=new SquareContourDetector_X2(i_size,i_dist_factor_ref);\r
+ this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
+ \r
+\r
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
+ int number_of_coord = (this._width + this._height) * 2;\r
+\r
+ // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
+ this._max_coord = number_of_coord;\r
+ this._xcoord = new int[number_of_coord * 2];\r
+ this._ycoord = new int[number_of_coord * 2];\r
+ }\r
+ private final int _max_coord;\r
+ private final int[] _xcoord;\r
+ private final int[] _ycoord;\r
+\r
+\r
+ /**\r
+ * arDetectMarker2を基にした関数\r
+ * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。\r
+ * directionの確定は行いません。\r
+ * @param i_raster\r
+ * 解析する2値ラスタイメージを指定します。\r
+ * @param o_square_stack\r
+ * 抽出した正方形候補を格納するリスト\r
+ * @throws NyARException\r
+ */\r
+ public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException\r
+ {\r
+ final RleLabelFragmentInfoStack flagment=this._stack;\r
+ final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> overlap = this._overlap_checker;\r
+\r
+ // 初期化\r
+\r
+ // マーカーホルダをリセット\r
+ o_square_stack.clear();\r
+\r
+ // ラベル数が0ならここまで(Labeling内部でソートするようにした。)\r
+ final int label_num=this._labeling.labeling(i_raster, 0, i_raster.getHeight(), flagment);\r
+ if (label_num < 1) {\r
+ return;\r
+ }\r
+ //ラベルをソートしておく\r
+ flagment.sortByArea();\r
+ RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
+\r
+\r
+ final int xsize = this._width;\r
+ final int ysize = this._height;\r
+ final int[] xcoord = this._xcoord;\r
+ final int[] ycoord = this._ycoord;\r
+ final int coord_max = this._max_coord;\r
+\r
+ //重なりチェッカの最大数を設定\r
+ overlap.setMaxLabels(label_num);\r
+\r
+ for (int i=0; i < label_num; i++) {\r
+ final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
+ final int label_area = label_pt.area;\r
+\r
+ // クリップ領域が画面の枠に接していれば除外\r
+ if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
+ continue;\r
+ }\r
+ if (label_pt.clip_t == 0 || label_pt.clip_b == ysize-1){\r
+ continue;\r
+ }\r
+ // 既に検出された矩形との重なりを確認\r
+ if (!overlap.check(label_pt)) {\r
+ // 重なっているようだ。\r
+ continue;\r
+ }\r
+ \r
+ // 輪郭を取得\r
+ final int coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
+ if (coord_num == coord_max) {\r
+ // 輪郭が大きすぎる。\r
+ continue;\r
+ }\r
+ //輪郭分析用に正規化する。\r
+ final int vertex1 = SquareContourDetector_X2.normalizeCoord(xcoord, ycoord, coord_num);\r
+\r
+ //ここから先が輪郭分析\r
+ NyARSquare square_ptr = o_square_stack.prePush();\r
+ if(!this._sqconvertor.coordToSquare(xcoord,ycoord,vertex1,coord_num,label_area,square_ptr)){\r
+ o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
+ continue; \r
+ }\r
+ // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
+ overlap.push(label_pt);\r
+ }\r
+ return; \r
+ }\r
+}\r
+\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARFixedFloat16Point3d;\r
+\r
+\r
+/**\r
+ * This class calculates ARMatrix from square information and holds it. --\r
+ * 変換行列を計算して、結果を保持するクラス。\r
+ * \r
+ */\r
+public class NyARTransMat_X2 implements INyARTransMat\r
+{\r
+ private final NyARFixedFloat16Point2d _center=new NyARFixedFloat16Point2d();\r
+ private final NyARFixedFloatTransOffset _offset=new NyARFixedFloatTransOffset();\r
+ private NyARFixedFloatRotMatrix _rotmatrix;\r
+ private NyARFixedFloatFitVecCalculator _calculator;\r
+ private NyARFixedFloatRotTransOptimize_O2 _mat_optimize;\r
+\r
+ public NyARTransMat_X2(NyARParam i_param) throws NyARException\r
+ {\r
+ final NyARPerspectiveProjectionMatrix pmat=i_param.getPerspectiveProjectionMatrix();\r
+ this._calculator=new NyARFixedFloatFitVecCalculator(pmat,i_param.getDistortionFactor());\r
+ this._rotmatrix = new NyARFixedFloatRotMatrix(pmat);\r
+ this._mat_optimize=new NyARFixedFloatRotTransOptimize_O2(pmat);\r
+ }\r
+\r
+ public void setCenter(double i_x, double i_y)\r
+ {\r
+ this._center.x= (long)i_x*NyMath.FIXEDFLOAT16_1;\r
+ this._center.y= (long)i_y*NyMath.FIXEDFLOAT16_1;\r
+ return;\r
+ }\r
+ /**\r
+ * 頂点順序をi_directionに対応して並べ替えます。\r
+ * @param i_square\r
+ * @param i_direction\r
+ * @param o_sqvertex_ref\r
+ * @param o_liner_ref\r
+ */\r
+ private final void initVertexOrder(NyARSquare i_square, int i_direction, NyARFixedFloat16Point2d[] o_sqvertex_ref, NyARLinear[] o_liner_ref)\r
+ {\r
+ //頂点順序を考慮した矩形の頂点情報\r
+ o_sqvertex_ref[0].x= (long)(i_square.sqvertex[(4 - i_direction) % 4].x*NyMath.FIXEDFLOAT16_1);\r
+ o_sqvertex_ref[0].y= (long)(i_square.sqvertex[(4 - i_direction) % 4].y*NyMath.FIXEDFLOAT16_1);\r
+ o_sqvertex_ref[1].x= (long)(i_square.sqvertex[(5 - i_direction) % 4].x*NyMath.FIXEDFLOAT16_1);\r
+ o_sqvertex_ref[1].y= (long)(i_square.sqvertex[(5 - i_direction) % 4].y*NyMath.FIXEDFLOAT16_1);\r
+ o_sqvertex_ref[2].x= (long)(i_square.sqvertex[(6 - i_direction) % 4].x*NyMath.FIXEDFLOAT16_1);\r
+ o_sqvertex_ref[2].y= (long)(i_square.sqvertex[(6 - i_direction) % 4].y*NyMath.FIXEDFLOAT16_1);\r
+ o_sqvertex_ref[3].x= (long)(i_square.sqvertex[(7 - i_direction) % 4].x*NyMath.FIXEDFLOAT16_1); \r
+ o_sqvertex_ref[3].y= (long)(i_square.sqvertex[(7 - i_direction) % 4].y*NyMath.FIXEDFLOAT16_1); \r
+ o_liner_ref[0]=i_square.line[(4 - i_direction) % 4];\r
+ o_liner_ref[1]=i_square.line[(5 - i_direction) % 4];\r
+ o_liner_ref[2]=i_square.line[(6 - i_direction) % 4];\r
+ o_liner_ref[3]=i_square.line[(7 - i_direction) % 4];\r
+ return;\r
+ }\r
+\r
+\r
+ private final NyARFixedFloat16Point2d[] __transMat_sqvertex_ref = NyARFixedFloat16Point2d.createArray(4);\r
+ private final NyARLinear[] __transMat_linear_ref=new NyARLinear[4];\r
+ private final NyARFixedFloat16Point3d __transMat_trans=new NyARFixedFloat16Point3d();\r
+ /**\r
+ * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )\r
+ * \r
+ * @param i_square\r
+ * 計算対象のNyARSquareオブジェクト\r
+ * @param i_direction\r
+ * @param i_width\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public void transMat(final NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
+ {\r
+ final NyARFixedFloat16Point2d[] sqvertex_ref = __transMat_sqvertex_ref;\r
+ final NyARLinear[] linear_ref=__transMat_linear_ref;\r
+ final NyARFixedFloat16Point3d trans=this.__transMat_trans;\r
+ \r
+ //計算用に頂点情報を初期化(順番調整)\r
+ initVertexOrder(i_square, i_direction, sqvertex_ref,linear_ref);\r
+ \r
+ //基準矩形を設定\r
+ this._offset.setSquare((long)(i_width*NyMath.FIXEDFLOAT16_1),this._center);\r
+\r
+ // rotationを矩形情報から計算\r
+ this._rotmatrix.initRotBySquare(linear_ref,sqvertex_ref);\r
+\r
+ //平行移動量計算機にオフセット頂点をセット\r
+ this._calculator.setOffsetSquare(this._offset);\r
+ \r
+ //平行移動量計算機に適応先矩形の情報をセット\r
+ this._calculator.setFittedSquare(sqvertex_ref); \r
+\r
+ //回転行列の平行移動量の計算\r
+ this._calculator.calculateTransfer(this._rotmatrix,trans);\r
+ \r
+ //計算結果の最適化(this._rotmatrix,trans)\r
+ this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);\r
+ \r
+ // マトリクスの保存\r
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,o_result_conv);\r
+ return;\r
+ }\r
+ /**\r
+ * double arGetTransMatCont( ARMarkerInfo *marker_info, double prev_conv[3][4],double center[2], double width, double conv[3][4] )\r
+ * \r
+ * @param i_square\r
+ * @param i_direction\r
+ * マーカーの方位を指定する。\r
+ * @param i_width\r
+ * @param io_result_conv\r
+ * 計算履歴を持つNyARTransMatResultオブジェクトを指定する。 履歴を持たない場合は、transMatと同じ処理を行う。\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public void transMatContinue(NyARSquare i_square, int i_direction, double i_width, NyARTransMatResult io_result_conv) throws NyARException\r
+ {\r
+ /* 今度実装\r
+ final NyARDoublePoint2d[] sqvertex_ref = __transMat_sqvertex_ref;\r
+ final NyARLinear[] linear_ref=__transMat_linear_ref;\r
+ final NyARDoublePoint3d trans=this.__transMat_trans;\r
+\r
+ // io_result_convが初期値なら、transMatで計算する。\r
+ if (!io_result_conv.hasValue()) {\r
+ this.transMat(i_square, i_direction, i_width, io_result_conv);\r
+ return;\r
+ }\r
+ \r
+ //基準矩形を設定\r
+ this._offset.setSquare(i_width,this._center);\r
+\r
+ // rotationを矩形情報を一つ前の変換行列で初期化\r
+ this._rotmatrix.initRotByPrevResult(io_result_conv);\r
+\r
+ //平行移動量計算機に、オフセット頂点をセット\r
+ this._calculator.setOffsetSquare(this._offset);\r
+ \r
+ //平行移動量計算機に、適応先矩形の情報をセット\r
+ this._calculator.setFittedSquare(sqvertex_ref); \r
+ \r
+ //回転行列の平行移動量の計算\r
+ this._calculator.calculateTransfer(this._rotmatrix,trans);\r
+ \r
+ //計算結果の最適化(this._rotmatrix,trans)\r
+ final double err=this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);\r
+ \r
+ //計算結果を保存\r
+ io_result_conv.updateMatrixValue(this._rotmatrix, this._offset.point, trans);\r
+\r
+ // エラー値が許容範囲でなければTransMatをやり直し\r
+ if (err > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR) {\r
+ // rotationを矩形情報で初期化\r
+ this._rotmatrix.initRotBySquare(linear_ref,sqvertex_ref);\r
+ //回転行列の平行移動量の計算\r
+ this._calculator.calculateTransfer(this._rotmatrix,trans);\r
+ //計算結果の最適化(this._rotmatrix,trans)\r
+ final double err2=this._mat_optimize.optimize(this._rotmatrix,trans,this._calculator);\r
+ //エラー値が低かったら値を差換え\r
+ if (err2 < err) {\r
+ // 良い値が取れたら、差換え\r
+ io_result_conv.updateMatrixValue(this._rotmatrix, this._offset.point, trans);\r
+ }\r
+ } \r
+ return;*/\r
+ NyARException.notImplement();\r
+ }\r
+ public void updateMatrixValue(NyARFixedFloatRotMatrix i_rot, NyARFixedFloat16Point3d i_off, NyARFixedFloat16Point3d i_trans,NyARTransMatResult o_result)\r
+ {\r
+ o_result.m00=(double)i_rot.m00/NyMath.FIXEDFLOAT24_1;\r
+ o_result.m01=(double)i_rot.m01/NyMath.FIXEDFLOAT24_1;\r
+ o_result.m02=(double)i_rot.m02/NyMath.FIXEDFLOAT24_1;\r
+ o_result.m03=(double)(((i_rot.m00 * i_off.x + i_rot.m01 * i_off.y + i_rot.m02 * i_off.z)>>24) + i_trans.x)/NyMath.FIXEDFLOAT16_1;\r
+\r
+ o_result.m10 =(double)i_rot.m10/NyMath.FIXEDFLOAT24_1;\r
+ o_result.m11 =(double)i_rot.m11/NyMath.FIXEDFLOAT24_1;\r
+ o_result.m12 =(double)i_rot.m12/NyMath.FIXEDFLOAT24_1;\r
+ o_result.m13 =(double)(((i_rot.m10 * i_off.x + i_rot.m11 * i_off.y + i_rot.m12 * i_off.z)>>24) + i_trans.y)/NyMath.FIXEDFLOAT16_1;\r
+\r
+ o_result.m20 =(double)i_rot.m20/NyMath.FIXEDFLOAT24_1;\r
+ o_result.m21 =(double)i_rot.m21/NyMath.FIXEDFLOAT24_1;\r
+ o_result.m22 =(double)i_rot.m22/NyMath.FIXEDFLOAT24_1;\r
+ o_result.m23 =(double)(((i_rot.m20 * i_off.x + i_rot.m21 * i_off.y + i_rot.m22 * i_off.z)>>24) + i_trans.z)/NyMath.FIXEDFLOAT16_1;\r
+ \r
+ final NyARFixedFloat16Point3d angle=i_rot.refAngle();\r
+\r
+ o_result.has_value = true;\r
+ return;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+public class NyMath\r
+{\r
+ public final static long FIXEDFLOAT24_1=0x1000000L;\r
+ public final static long FIXEDFLOAT24_0_25=FIXEDFLOAT24_1/4;\r
+ public final static long FIXEDFLOAT16_1=0x10000L; \r
+ public final static long FIXEDFLOAT16_0_25=FIXEDFLOAT16_1/4; \r
+ public final static long FIXEDFLOAT8_1=0x100L;\r
+ \r
+ private final static int FIXEDFLOAT16I_1=(int)FIXEDFLOAT16_1; \r
+ private final static int FIXEDFLOAT16I_0_25=(int)FIXEDFLOAT16_1/4; \r
+ \r
+ \r
+ \r
+\r
+ private final static int FF16_PI=(int)(Math.PI*FIXEDFLOAT16_1);\r
+ private final static int FF16_2PI=(int)(2 *FF16_PI);\r
+ private final static int FF16_05PI=(int)(FF16_PI/2);\r
+ /* sinテーブルは0-2PIを1024分割\r
+ * acosテーブルは0-1を256分割\r
+ */\r
+ private final static int[] sin_table=new int[339];\r
+ private final static int[] acos_table=new int[1537];\r
+ private final static int SQRT_LOOP=10;\r
+ /**\r
+ * http://www.geocities.co.jp/SiliconValley-PaloAlto/5438/\r
+ * 参考にしました。\r
+ * 少数点部が16bitの変数の平方根を求めます。\r
+ * 戻り値の小数点部分は16bitです。\r
+ * @param i_v\r
+ * @return\r
+ */\r
+ public static long sqrtFixdFloat16(long i_ff16)\r
+ {\r
+ long t=0,s;\r
+ s=i_ff16>0?i_ff16:-i_ff16;\r
+ if(i_ff16==0){\r
+ return 0;\r
+ }\r
+ for(int i=SQRT_LOOP;i>0;i--){\r
+ t = s;\r
+ s = (t+((i_ff16<<16)/t))>>1;\r
+ if(s==t){\r
+ break;\r
+ }\r
+ };\r
+ return t;\r
+ }\r
+ public static long sqrtFixdFloat(long i_ff,int i_bit)\r
+ {\r
+ long t=0,s;\r
+ s=i_ff>0?i_ff:-i_ff;\r
+ if(i_ff==0){\r
+ return 0;\r
+ }\r
+ for(int i=SQRT_LOOP;i>0;i--){\r
+ t = s;\r
+ s = (t+((i_ff<<i_bit)/t))>>1;\r
+ if(s==t){\r
+ break;\r
+ }\r
+ }\r
+ return t;\r
+ }\r
+ public static int acosFixedFloat16(int i_ff24)\r
+ {/* \r
+ long x=i_ff24>>8;\r
+ long x2=(x*x)>>16;\r
+ long x3=(x2*x)>>16;\r
+ long x4=(x2*x2)>>16;\r
+// return FF16_05PI-(int)(x+x3/6+(((3*x3*x2/(2*4*5)+(3*5*x4*x3)/(2*4*6*7)))>>16));\r
+*/ \r
+ int result;\r
+ int abs_ff24=i_ff24>0?i_ff24:-i_ff24;\r
+ //(0<=n<=0.25) 0<=0-16384(65536/4)まではy=PI/2-xので近似\r
+ //(0.25<n<=1/2PI) 16385-65536までは(128ステップ単位)のテーブルを使用 \r
+\r
+ if(abs_ff24<FIXEDFLOAT24_0_25){\r
+ //0.25までの範囲は、2次の近似式\r
+ result=(i_ff24>>8);\r
+ return FF16_05PI-result+((((result*result)>>16)*result)>>16)/6;\r
+ }else{\r
+ result=acos_table[((abs_ff24>>8)-FIXEDFLOAT16I_0_25)>>5];\r
+ if (i_ff24 < 0) {\r
+ return FF16_PI-result;\r
+ }else{\r
+ return result;\r
+ }\r
+ }\r
+// return (int)(Math.acos((double)i_ff24/0x1000000)*0x10000);\r
+ }\r
+ /**\r
+ * 誤差確認用の関数\r
+ * @param args\r
+ */\r
+ public static void main(String[] args)\r
+ {\r
+ //sin\r
+ NyMath.initialize();\r
+// for(int i=0;i<3600;i++){\r
+// int s=cosFixedFloat24((int)(FIXEDFLOAT16I_1*i*Math.PI/1800));\r
+// System.out.println((double)(s-(int)(FIXEDFLOAT24_1*Math.cos((i*Math.PI/1800))))/FIXEDFLOAT24_1);\r
+// }\r
+ //acos\r
+ for(int i=-1000;i<1000;i++){\r
+ int s=acosFixedFloat16((int)(FIXEDFLOAT24_1*i/1000));\r
+// System.out.println((double)(s-(int)(FIXEDFLOAT16_1*Math.acos((double)i/1000)))/FIXEDFLOAT16_1);\r
+ System.out.println((double)s/FIXEDFLOAT16I_1);\r
+ }\r
+ }\r
+ public static int sinFixedFloat24(int i_ff16)\r
+ {\r
+ int result;\r
+ //i_ff16を0-2πに制限\r
+ int rad=i_ff16%FF16_2PI;\r
+ if(rad<0){\r
+ rad=rad+FF16_2PI;\r
+ }\r
+ //4ブロックに分割\r
+ int dv=rad/FF16_05PI;\r
+ //radを0-0.5PIに制限\r
+ rad=rad-dv*FF16_05PI;\r
+ //radをdvにより補正\r
+ if(dv==1 || dv==3){\r
+ rad=FF16_05PI-rad;\r
+ }\r
+ //(0<=n<=0.25) 0<=0-16384(65536/4)まではy=xので近似\r
+ //(0.25<n<=1/2PI) 16385-102944までは(256ステップ単位)のテーブルを使用 \r
+ //負にする\r
+ if(rad<FIXEDFLOAT16_0_25){\r
+ result=rad<<8;\r
+ }else{\r
+ result=sin_table[(rad-FIXEDFLOAT16I_0_25)>>8];\r
+ }\r
+ if(dv>=2){\r
+ result=-result;\r
+ }\r
+ return result;\r
+// return (int)(Math.sin((double)i_ff16/0x10000)*0x1000000);\r
+ }\r
+ public static int cosFixedFloat24(int i_ff16)\r
+ {\r
+ int result;\r
+ //i_ff16を0-2πに制限\r
+ int rad=(i_ff16+FF16_05PI)%FF16_2PI;\r
+ if(rad<0){\r
+ rad=rad+FF16_2PI;\r
+ }\r
+ //4ブロックに分割\r
+ int dv=rad/FF16_05PI;\r
+ //radを0-0.5PIに制限\r
+ rad=rad-dv*FF16_05PI;\r
+ //radをdvにより補正\r
+ if(dv==1 || dv==3){\r
+ rad=FF16_05PI-rad;\r
+ }\r
+ //(0<=n<=0.25) 0<=0-16384(65536/4)まではy=xので近似\r
+ //(0.25<n<=1/2PI) 16385-102944までは(256ステップ単位)のテーブルを使用 \r
+ //負にする\r
+ if(rad<FIXEDFLOAT16_0_25){\r
+ result=rad<<8;\r
+ }else{\r
+ result=sin_table[(rad-FIXEDFLOAT16I_0_25)>>8];\r
+ }\r
+ if(dv>=2){\r
+ result=-result;\r
+ }\r
+ return result;\r
+// return (int)(Math.cos((double)i_ff16/0x10000)*0x1000000);\r
+ }\r
+ public static void initialize()\r
+ {\r
+\r
+ int step;\r
+ step=FIXEDFLOAT16I_0_25+256;\r
+ for(int i=0;i<339;i++){\r
+ sin_table[i]=(int)((Math.sin((double) step / (double) FIXEDFLOAT16I_1))*FIXEDFLOAT24_1);\r
+ step+=256;\r
+ }\r
+ //acosテーブル初期化\r
+ step=FIXEDFLOAT16I_0_25+32;\r
+ for (int i = 0; i < 1537; i++) {\r
+ acos_table[i] =(int)((Math.acos((double) step/(double) FIXEDFLOAT16I_1))*FIXEDFLOAT16_1);\r
+ step+=32;\r
+ }\r
+ return;\r
+ }\r
+ public static void printF16(long i_value)\r
+ {\r
+ System.out.println((double)i_value/0x10000);\r
+ return;\r
+ }\r
+ public static void printF24(long i_value)\r
+ {\r
+ System.out.println((double)i_value/0x1000000);\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import java.io.*;\r
+import java.util.*;\r
+\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+\r
+\r
+/**\r
+ * 320x240のBGRA32で記録されたRAWイメージから、1種類のパターンを認識し、\r
+ * その変換行列を1000回求め、それにかかったミリ秒時間を表示します。\r
+ * \r
+ */\r
+public class RawFileTest_X2\r
+{\r
+ private final String code_file = "../../Data/patt.hiro";\r
+\r
+ private final String data_file = "../../Data/320x240ABGR.raw";\r
+\r
+ private final String camera_file = "../../Data/camera_para.dat";\r
+\r
+ public RawFileTest_X2()\r
+ {\r
+ NyMath.initialize();\r
+ }\r
+\r
+\r
+ public void Test_arDetectMarkerLite() throws Exception\r
+ {\r
+ // AR用カメラパラメタファイルをロード\r
+ NyARParam ap = new NyARParam();\r
+ ap.loadARParamFromFile(camera_file);\r
+ ap.changeScreenSize(320, 240);\r
+\r
+ // AR用のパターンコードを読み出し\r
+ NyARCode code = new NyARCode(16, 16);\r
+ code.loadARPattFromFile(code_file);\r
+\r
+ // 試験イメージの読み出し(320x240 BGRAのRAWデータ)\r
+ File f = new File(data_file);\r
+ FileInputStream fs = new FileInputStream(data_file);\r
+ byte[] buf = new byte[(int) f.length()];\r
+ fs.read(buf);\r
+ INyARRgbRaster ra = NyARRgbRaster_BGRA.wrap(buf, 320, 240);\r
+ // Blank_Raster ra=new Blank_Raster(320, 240);\r
+\r
+ // 1パターンのみを追跡するクラスを作成\r
+// NyARSingleDetectMarker_Quad ar = new NyARSingleDetectMarker_Quad(ap, code, 80.0);\r
+ NyARSingleDetectMarker_X2 ar = new NyARSingleDetectMarker_X2(ap, code, 80.0,ra.getBufferReader().getBufferType());\r
+ NyARTransMatResult result_mat = new NyARTransMatResult();\r
+ ar.setContinueMode(false);\r
+ ar.detectMarkerLite(ra, 100);\r
+ ar.getTransmationMatrix(result_mat);\r
+\r
+ // マーカーを検出\r
+ Date d2 = new Date();\r
+ for (int i = 0; i < 1000; i++) {\r
+ // 変換行列を取得\r
+ ar.detectMarkerLite(ra, 100);\r
+ ar.getTransmationMatrix(result_mat);\r
+ }\r
+ Date d = new Date();\r
+ System.out.println(d.getTime() - d2.getTime());\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+\r
+ try {\r
+ RawFileTest_X2 t = new RawFileTest_X2();\r
+ // t.Test_arGetVersion();\r
+ t.Test_arDetectMarkerLite();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * Capture Test NyARToolkitCSサンプルプログラム\r
+ * --------------------------------------------------------------------------------\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.analyzer.threshold.NyARRasterThresholdAnalyzerBuilder_Threshold;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilterBuilder_RgbToBin;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilter_ARToolkitThreshold;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+\r
+/**\r
+ * このクラスは、同時に1個のマーカを処理することのできる、アプリケーションプロセッサです。\r
+ * マーカの出現・移動・消滅を、イベントで通知することができます。\r
+ * クラスには複数のマーカを登録できます。一つのマーカが見つかると、プロセッサは継続して同じマーカを\r
+ * 1つだけ認識し続け、見失うまでの間は他のマーカを認識しません。\r
+ * \r
+ * イベントは、 OnEnter→OnUpdate[n]→OnLeaveの順で発生します。\r
+ * マーカが見つかるとまずOnEnterが1度発生して、何番のマーカが発見されたかがわかります。\r
+ * 次にOnUpdateにより、現在の変換行列が連続して渡されます。最後にマーカを見失うと、OnLeave\r
+ * イベントが発生します。\r
+ * \r
+ */\r
+public abstract class SingleARMarkerProcesser_X2\r
+{\r
+ /**selectARCodeIndexFromListが値を返す時に使う変数型です。\r
+ */\r
+\r
+ private class TResult_selectARCodeIndex\r
+ {\r
+ public int direction;\r
+\r
+ public double confidence;\r
+\r
+ public int code_index;\r
+ }\r
+ /**オーナーが自由に使えるタグ変数です。\r
+ */\r
+ public Object tag;\r
+\r
+ private int _lost_delay_count = 0;\r
+\r
+ private int _lost_delay = 5;\r
+\r
+ private INyARSquareContourDetector _square_detect;\r
+\r
+ //<X2 patch>\r
+ protected NyARTransMat_X2 _transmat;\r
+ //</X2 patch>\r
+ private double _marker_width;\r
+\r
+ private NyARMatchPatt_Color_WITHOUT_PCA[] _match_patt;\r
+\r
+ private NyARSquareStack _square_list = new NyARSquareStack(100);\r
+\r
+ private INyARColorPatt _patt = null;\r
+\r
+ private double _cf_threshold_new = 0.30;\r
+ private double _cf_threshold_exist = 0.15;\r
+ \r
+ private int _threshold = 110;\r
+ // [AR]検出結果の保存用\r
+ private NyARBinRaster _bin_raster;\r
+\r
+ private NyARRasterFilter_ARToolkitThreshold _tobin_filter;\r
+\r
+ protected int _current_arcode_index = -1;\r
+\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+ private NyARRasterThresholdAnalyzerBuilder_Threshold _threshold_detect;\r
+ \r
+ protected SingleARMarkerProcesser_X2()\r
+ {\r
+ return;\r
+ }\r
+\r
+\r
+ protected void initInstance(NyARParam i_param,int i_raster_type) throws NyARException\r
+ {\r
+ NyARIntSize scr_size = i_param.getScreenSize();\r
+ // 解析オブジェクトを作る\r
+//<X2 patch>\r
+ this._square_detect = new NyARSquareDetector_X2(i_param.getDistortionFactor(), scr_size);\r
+ this._transmat = new NyARTransMat_X2(i_param);\r
+//</X2 patch>\r
+\r
+ this._tobin_filter=new NyARRasterFilter_ARToolkitThreshold(110,i_raster_type);\r
+\r
+ // 2値画像バッファを作る\r
+ this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h);\r
+ this._threshold_detect=new NyARRasterThresholdAnalyzerBuilder_Threshold(15,i_raster_type,4);\r
+ return;\r
+ }\r
+\r
+ /**検出するマーカコードの配列を指定します。 検出状態でこの関数を実行すると、\r
+ * オブジェクト状態に強制リセットがかかります。\r
+ */\r
+ public void setARCodeTable(NyARCode[] i_ref_code_table, int i_code_resolution, double i_marker_width)\r
+ {\r
+ if (this._current_arcode_index != -1) {\r
+ // 強制リセット\r
+ reset(true);\r
+ }\r
+ //検出するマーカセット、情報、検出器を作り直す。(1ピクセル4ポイントサンプリング,マーカのパターン領域は50%)\r
+ this._patt = new NyARColorPatt_Perspective_O2(i_code_resolution, i_code_resolution,4,25);\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(i_code_resolution, i_code_resolution);\r
+ this._marker_width = i_marker_width;\r
+\r
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA[i_ref_code_table.length];\r
+ for(int i=0;i<i_ref_code_table.length;i++){\r
+ this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code_table[i]);\r
+ }\r
+ return;\r
+ }\r
+\r
+ public void reset(boolean i_is_force)\r
+ {\r
+ if (this._current_arcode_index != -1 && i_is_force == false) {\r
+ // 強制書き換えでなければイベントコール\r
+ this.onLeaveHandler();\r
+ }\r
+ // カレントマーカをリセット\r
+ this._current_arcode_index = -1;\r
+ return;\r
+ }\r
+\r
+ public void detectMarker(INyARRgbRaster i_raster) throws NyARException\r
+ {\r
+ // サイズチェック\r
+ assert(this._bin_raster.getSize().isEqualSize(i_raster.getSize().w, i_raster.getSize().h));\r
+\r
+ // コードテーブルが無ければここで終わり\r
+ if (this._match_patt== null) {\r
+ return;\r
+ }\r
+\r
+ // ラスタを(1/4の画像の)2値イメージに変換する.\r
+ this._tobin_filter.setThreshold(this._threshold);\r
+ this._tobin_filter.doFilter(i_raster, this._bin_raster);\r
+\r
+ NyARSquareStack square_stack = this._square_list;\r
+ // スクエアコードを探す\r
+ this._square_detect.detectMarkerCB(this._bin_raster, square_stack);\r
+ // 認識処理\r
+ if (this._current_arcode_index == -1) { // マーカ未認識\r
+ detectNewMarker(i_raster, square_stack);\r
+ } else { // マーカ認識中\r
+ detectExistMarker(i_raster, square_stack, this._current_arcode_index);\r
+ }\r
+ return;\r
+ }\r
+\r
+ \r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ \r
+ /**ARCodeのリストから、最も一致するコード番号を検索します。\r
+ */\r
+ private boolean selectARCodeIndexFromList(INyARRgbRaster i_raster, NyARSquare i_square, TResult_selectARCodeIndex o_result) throws NyARException\r
+ {\r
+ // 現在コードテーブルはアクティブ?\r
+ if (this._match_patt==null) {\r
+ return false;\r
+ }\r
+ // 評価基準になるパターンをイメージから切り出す\r
+ if (!this._patt.pickFromRaster(i_raster, i_square.imvertex)) {\r
+ return false;\r
+ }\r
+ //評価データを作成して、評価器にセット\r
+ this._deviation_data.setRaster(this._patt); \r
+ final NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+ int code_index = 0;\r
+ int dir = 0;\r
+ double c1 = 0;\r
+ // コードと比較する\r
+ for (int i = 0; i < this._match_patt.length; i++) {\r
+ this._match_patt[i].evaluate(this._deviation_data,mr);\r
+ double c2 = mr.confidence;\r
+ if (c1 < c2) {\r
+ code_index = i;\r
+ c1 = c2;\r
+ dir = mr.direction;\r
+ }\r
+ }\r
+ o_result.code_index = code_index;\r
+ o_result.direction = dir;\r
+ o_result.confidence = c1;\r
+ return true;\r
+ }\r
+\r
+ private TResult_selectARCodeIndex __detect_X_Marker_detect_result = new TResult_selectARCodeIndex();\r
+\r
+ /**新規マーカ検索 現在認識中のマーカがないものとして、最も認識しやすいマーカを1個認識します。\r
+ */\r
+ private void detectNewMarker(INyARRgbRaster i_raster, NyARSquareStack i_stack) throws NyARException\r
+ {\r
+ int number_of_square = i_stack.getLength();\r
+ double cf = 0;\r
+ int dir = 0;\r
+ int code_index = -1;\r
+ int square_index = 0;\r
+ TResult_selectARCodeIndex detect_result = this.__detect_X_Marker_detect_result;\r
+ for (int i = 0; i < number_of_square; i++) {\r
+ if (!selectARCodeIndexFromList(i_raster, (i_stack.getItem(i)), detect_result)) {\r
+ // 見つからない。\r
+ return;\r
+ }\r
+ if (detect_result.confidence < this._cf_threshold_new) {\r
+ continue;\r
+ }\r
+ if (detect_result.confidence < cf) {\r
+ // 一致度が低い。\r
+ continue;\r
+ }\r
+ cf = detect_result.confidence;\r
+ code_index = detect_result.code_index;\r
+ square_index = i;\r
+ dir = detect_result.direction;\r
+ }\r
+ // 認識状態を更新\r
+ final boolean is_id_found=updateStatus(this._square_list.getItem(square_index), code_index, cf, dir);\r
+ //閾値フィードバック(detectExistMarkerにもあるよ)\r
+ if(!is_id_found){\r
+ //マーカがなければ、探索+DualPTailで基準輝度検索\r
+ this._threshold_detect.analyzeRaster(i_raster);\r
+ this._threshold=(this._threshold+this._threshold_detect.getThreshold())/2;\r
+ }\r
+ }\r
+\r
+ /**マーカの継続認識 現在認識中のマーカを優先して認識します。 \r
+ * (注)この機能はたぶん今後いろいろ発展するからNewと混ぜないこと。\r
+ */\r
+ private void detectExistMarker(INyARRgbRaster i_raster, NyARSquareStack i_stack, int i_current_id) throws NyARException\r
+ {\r
+ int number_of_square = i_stack.getLength();\r
+ double cf = 0;\r
+ int dir = 0;\r
+ int code_index = -1;\r
+ int square_index = 0;\r
+ TResult_selectARCodeIndex detect_result = this.__detect_X_Marker_detect_result;\r
+ for (int i = 0; i < number_of_square; i++) {\r
+ if (!selectARCodeIndexFromList(i_raster,i_stack.getItem(i), detect_result)) {\r
+ // 見つからない。\r
+ return;\r
+ }\r
+ // 現在のマーカを認識したか?\r
+ if (detect_result.code_index != i_current_id) {\r
+ // 認識中のマーカではないので無視\r
+ continue;\r
+ }\r
+ if (detect_result.confidence < this._cf_threshold_exist) {\r
+ continue;\r
+ }\r
+ if (detect_result.confidence < cf) {\r
+ // 一致度が高い方を選ぶ\r
+ continue;\r
+ }\r
+ cf = detect_result.confidence;\r
+ code_index = detect_result.code_index;\r
+ dir = detect_result.direction;\r
+ square_index = i;\r
+ }\r
+ // 認識状態を更新\r
+ final boolean is_id_found=updateStatus(this._square_list.getItem(square_index), code_index, cf, dir);\r
+ //閾値フィードバック(detectExistMarkerにもあるよ)\r
+ if(!is_id_found){\r
+ //マーカがなければ、探索+DualPTailで基準輝度検索\r
+ this._threshold_detect.analyzeRaster(i_raster);\r
+ this._threshold=(this._threshold+this._threshold_detect.getThreshold())/2;\r
+ }\r
+ \r
+ }\r
+\r
+ private NyARTransMatResult __NyARSquare_result = new NyARTransMatResult();\r
+\r
+ /** オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。\r
+ * 戻り値は、「実際にマーカを発見する事ができたか」です。クラスの状態とは異なります。\r
+ */\r
+ private boolean updateStatus(NyARSquare i_square, int i_code_index, double i_cf, int i_dir) throws NyARException\r
+ {\r
+ NyARTransMatResult result = this.__NyARSquare_result;\r
+ if (this._current_arcode_index < 0) {// 未認識中\r
+ if (i_code_index < 0) {// 未認識から未認識の遷移\r
+ // なにもしないよーん。\r
+ return false;\r
+ } else {// 未認識から認識の遷移\r
+ this._current_arcode_index = i_code_index;\r
+ // イベント生成\r
+ // OnEnter\r
+ this.onEnterHandler(i_code_index);\r
+ // 変換行列を作成\r
+ this._transmat.transMat(i_square, i_dir, this._marker_width, result);\r
+ // OnUpdate\r
+ this.onUpdateHandler(i_square, result);\r
+ this._lost_delay_count = 0;\r
+ return true;\r
+ }\r
+ } else {// 認識中\r
+ if (i_code_index < 0) {// 認識から未認識の遷移\r
+ this._lost_delay_count++;\r
+ if (this._lost_delay < this._lost_delay_count) {\r
+ // OnLeave\r
+ this._current_arcode_index = -1;\r
+ this.onLeaveHandler();\r
+ }\r
+ return false;\r
+ } else if (i_code_index == this._current_arcode_index) {// 同じARCodeの再認識\r
+ // イベント生成\r
+ // 変換行列を作成\r
+ this._transmat.transMat(i_square, i_dir, this._marker_width, result);\r
+ // OnUpdate\r
+ this.onUpdateHandler(i_square, result);\r
+ this._lost_delay_count = 0;\r
+ return true;\r
+ } else {// 異なるコードの認識→今はサポートしない。\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ }\r
+\r
+ protected abstract void onEnterHandler(int i_code);\r
+\r
+ protected abstract void onLeaveHandler();\r
+\r
+ protected abstract void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result);\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.sandbox.x2;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARI64Linear;\r
+import jp.nyatla.nyartoolkit.core.types.NyARI64Point2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARI64Matrix22;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+\r
+public class SquareContourDetector_X2\r
+{\r
+ private final int PCA_LENGTH=20;\r
+ private final int[] _xpos=new int[PCA_LENGTH];\r
+ private final int[] _ypos=new int[PCA_LENGTH];\r
+ private final int[] __detectMarker_mkvertex = new int[5];\r
+ private final NyARFixedFloatVertexCounter __getSquareVertex_wv1 = new NyARFixedFloatVertexCounter();\r
+ private final NyARFixedFloatVertexCounter __getSquareVertex_wv2 = new NyARFixedFloatVertexCounter();\r
+ private final NyARFixedFloatPca2d _pca;\r
+ private final NyARI64Matrix22 __getSquareLine_evec=new NyARI64Matrix22();\r
+ private final NyARI64Point2d __getSquareLine_mean=new NyARI64Point2d();\r
+ private final NyARI64Point2d __getSquareLine_ev=new NyARI64Point2d();\r
+ private final NyARI64Linear[] __getSquareLine_i64liner=NyARI64Linear.createArray(4);\r
+ private final NyARFixedFloatObserv2IdealMap _dist_factor;\r
+ public SquareContourDetector_X2(NyARIntSize i_size,NyARCameraDistortionFactor i_distfactor_ref)\r
+ {\r
+ //歪み計算テーブルを作ると、8*width/height*2の領域を消費します。\r
+ //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。\r
+ this._dist_factor = new NyARFixedFloatObserv2IdealMap(i_distfactor_ref,i_size);\r
+\r
+\r
+ // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
+ this._pca=new NyARFixedFloatPca2d();\r
+ return;\r
+ }\r
+\r
+ public boolean coordToSquare(int[] i_xcoord,int[] i_ycoord,int i_st_index,int i_coord_num,int i_label_area,NyARSquare o_square) throws NyARException\r
+ {\r
+\r
+ final int[] mkvertex = this.__detectMarker_mkvertex;\r
+\r
+ // 頂点情報を取得\r
+ if (!getSquareVertex(i_xcoord, i_ycoord, i_st_index, i_coord_num, i_label_area, mkvertex)) {\r
+ // 頂点の取得が出来なかったので破棄\r
+ return false;\r
+ }\r
+ // マーカーを検出\r
+ if (!getSquareLine(mkvertex, i_xcoord, i_ycoord, o_square)){\r
+ // 矩形が成立しなかった。\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+ \r
+ private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException\r
+ {\r
+ final NyARLinear[] l_line = o_square.line;\r
+ final NyARI64Matrix22 evec=this.__getSquareLine_evec;\r
+ final NyARI64Point2d mean=this.__getSquareLine_mean;\r
+ final NyARI64Point2d ev=this.__getSquareLine_ev;\r
+ final NyARI64Linear[] i64liner=this.__getSquareLine_i64liner;\r
+ \r
+ for (int i = 0; i < 4; i++) {\r
+// final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;\r
+ final int w1 = ((((i_mkvertex[i + 1] - i_mkvertex[i] + 1)<<8)*13)>>8) + (1<<7);\r
+ final int st = i_mkvertex[i] + (w1>>8);\r
+ final int ed = i_mkvertex[i + 1] - (w1>>8);\r
+ int n = ed - st + 1;\r
+ if (n < 2) {\r
+ // nが2以下でmatrix.PCAを計算することはできないので、エラー\r
+ return false;\r
+ }\r
+ //配列作成\r
+ n=this._dist_factor.observ2IdealSampling(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos,PCA_LENGTH);\r
+ //主成分分析する。\r
+ this._pca.pcaF16(this._xpos,this._ypos, n,evec, ev,mean);\r
+ final NyARI64Linear l_line_i = i64liner[i];\r
+ l_line_i.run = evec.m01;// line[i][0] = evec->m[1];\r
+ l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0];\r
+ l_line_i.intercept = -((l_line_i.run * mean.x + l_line_i.rise * mean.y)>>16);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);\r
+ }\r
+\r
+ final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
+ final NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
+ for (int i = 0; i < 4; i++) {\r
+ final NyARI64Linear l_line_i = i64liner[i];\r
+ final NyARI64Linear l_line_2 = i64liner[(i + 3) % 4];\r
+ final long w1 =(l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise)>>16;\r
+ if (w1 == 0) {\r
+ return false;\r
+ }\r
+ l_sqvertex[i].x = (double)((l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1)/65536.0;\r
+ l_sqvertex[i].y = (double)((l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1)/65536.0;\r
+ // 頂点インデクスから頂点座標を得て保存\r
+ l_imvertex[i].x = i_xcoord[i_mkvertex[i]];\r
+ l_imvertex[i].y = i_ycoord[i_mkvertex[i]];\r
+ l_line[i].dy=(double)l_line_i.run/65536.0;\r
+ l_line[i].dx=(double)l_line_i.rise/65536.0;\r
+ l_line[i].c=(double)l_line_i.intercept/65536.0;\r
+ }\r
+ return true;\r
+ } \r
+ private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)\r
+ {\r
+ final NyARFixedFloatVertexCounter wv1 = this.__getSquareVertex_wv1;\r
+ final NyARFixedFloatVertexCounter wv2 = this.__getSquareVertex_wv2;\r
+ final int end_of_coord = i_vertex1_index + i_coord_num - 1;\r
+ final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];\r
+ final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];\r
+ int dmax = 0;\r
+ int v1 = i_vertex1_index;\r
+ for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)\r
+ // {\r
+ final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);\r
+ if (d > dmax) {\r
+ dmax = d;\r
+ v1 = i;\r
+ }\r
+ }\r
+ //final double thresh = (i_area / 0.75) * 0.01;\r
+ final long thresh_f16 =(i_area<<16)/75;\r
+\r
+ o_vertex[0] = i_vertex1_index;\r
+\r
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh_f16)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<\r
+ // 0 ) {\r
+ return false;\r
+ }\r
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh_f16)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)\r
+ // < 0) {\r
+ return false;\r
+ }\r
+\r
+ int v2;\r
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) {\r
+ o_vertex[1] = wv1.vertex[0];\r
+ o_vertex[2] = v1;\r
+ o_vertex[3] = wv2.vertex[0];\r
+ } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {\r
+ //頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。\r
+ v2 = (v1-i_vertex1_index)/2+i_vertex1_index;\r
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh_f16)) {\r
+ return false;\r
+ }\r
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh_f16)) {\r
+ return false;\r
+ }\r
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
+ o_vertex[1] = wv1.vertex[0];\r
+ o_vertex[2] = wv2.vertex[0];\r
+ o_vertex[3] = v1;\r
+ } else {\r
+ return false;\r
+ }\r
+ } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {\r
+ //v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;\r
+ v2 = (v1+ end_of_coord)/2;\r
+\r
+ if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh_f16)) {\r
+ return false;\r
+ }\r
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh_f16)) {\r
+ return false;\r
+ }\r
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
+ o_vertex[1] = v1;\r
+ o_vertex[2] = wv1.vertex[0];\r
+ o_vertex[3] = wv2.vertex[0];\r
+ } else {\r
+ return false;\r
+ }\r
+ } else {\r
+ return false;\r
+ }\r
+ o_vertex[4] = end_of_coord;\r
+ return true;\r
+ }\r
+ \r
+ /**\r
+ * 輪郭線の矩形検出開始ポイントを特定して、座標を並べ替えます。\r
+ * 輪郭線の先頭から、対角線が最長になる点を1点検索し、それより前の区間をバッファの後方に接続します。\r
+ * 戻り値は対角線が最長になった点です。関数終了後、返却値+i_coord_numの要素が有効になります。\r
+ * @param i_xcoord\r
+ * @param i_ycoord\r
+ * @param i_coord_num\r
+ * @return\r
+ */\r
+ public static int normalizeCoord(int[] i_coord_x, int[] i_coord_y,int i_coord_num)\r
+ {\r
+ //\r
+ final int sx = i_coord_x[0];\r
+ final int sy = i_coord_y[0];\r
+ int d = 0;\r
+ int w, x, y;\r
+ int ret = 0;\r
+ for (int i = 1; i < i_coord_num; i++) {\r
+ x = i_coord_x[i] - sx;\r
+ y = i_coord_y[i] - sy;\r
+ w = x * x + y * y;\r
+ if (w > d) {\r
+ d = w;\r
+ ret = i;\r
+ }\r
+ // ここでうまく終了条件入れられないかな。\r
+ } \r
+ // vertex1を境界にして、後方に配列を連結\r
+ System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, ret);\r
+ System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, ret);\r
+ return ret;\r
+ } \r
+ \r
+}
\ No newline at end of file
--- /dev/null
+/* このソースは実験用のソースです。
+ * 動いたり動かなかったりします。
+ *
+ */
+package jp.nyatla.nyartoolkit.sandbox.x2;
+
+import javax.media.*;
+
+import javax.media.util.BufferToImage;
+import javax.media.format.*;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
+import jp.nyatla.nyartoolkit.sandbox.quadx2.*;
+import jp.nyatla.nyartoolkit.utils.j2se.LabelingBufferdImage;
+
+import jp.nyatla.nyartoolkit.core.*;
+
+import java.awt.*;
+
+import jp.nyatla.nyartoolkit.core.analyzer.raster.threshold.INyARRasterThresholdAnalyzer;
+import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabeling_ARToolKit;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.rasteranalyzer.threshold.NyARRasterThresholdAnalyzer_DiffHistgram;
+import jp.nyatla.nyartoolkit.core.rasterfilter.*;
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_RgbToGs;
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.gs2bin.*;
+import jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold.*;
+
+
+
+public class VisualTest extends Frame implements JmfCaptureListener
+{
+ private final String camera_file = "../../Data/camera_para.dat";
+
+ private JmfNyARRaster_RGB _raster;
+
+ private JmfCaptureDevice capture;
+ private NyARParam ap;
+ public VisualTest() throws NyARException, NyARException
+ {
+ setBounds(0, 0, 640 + 64, 720 + 64);
+ // キャプチャの準備
+ JmfCaptureDeviceList list=new JmfCaptureDeviceList();
+ capture=list.getDevice(0);
+ capture.setCaptureFormat(320,240,30.0f);
+ capture.setOnCapture(this);
+
+ // キャプチャイメージ用のラスタを準備
+ this._raster = new JmfNyARRaster_RGB(320, 240,capture.getCaptureFormat());
+
+ // AR用カメラパラメタファイルをロード
+ ap = new NyARParam();
+ ap.loadARParamFromFile(camera_file);
+ ap.changeScreenSize(320, 240);
+
+
+ }
+
+ private NyARBinRaster _binraster1 = new NyARBinRaster(160,120);
+
+ private NyARGrayscaleRaster _gsraster1 = new NyARGrayscaleRaster(320, 240);
+ private INyARRasterThresholdAnalyzer _tha=new NyARRasterThresholdAnalyzer_DiffHistgram();
+
+ private LabelingBufferdImage _bimg = new LabelingBufferdImage(320, 240);
+ private LabelingBufferdImage _bimg2 = new LabelingBufferdImage(160, 120);
+ private NyARRasterFilter_ARTTh_Quad _tobin_filter=new NyARRasterFilter_ARTTh_Quad(100);
+
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+
+ try {
+ // キャプチャしたバッファをラスタにセット
+ _raster.setBuffer(i_buffer);
+
+ Graphics g = getGraphics();
+ // キャプチャ画像
+ BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+ Image img = b2i.createImage(i_buffer);
+ this.getGraphics().drawImage(img, 32, 32, this);
+
+ // 画像1
+ INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbAve();
+// INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbMul();
+
+ filter_rgb2gs.doFilter(_raster, _gsraster1);
+ this._bimg.drawImage(this._gsraster1);
+ this.getGraphics().drawImage(this._bimg, 32 + 320, 32, 320 + 320 + 32, 240 + 32, 0, 240, 320, 0, this);
+ _tha.analyzeRaster(_gsraster1);
+ NyARRasterFilter_Threshold gs2bin=new NyARRasterFilter_Threshold(_tha.getThreshold());
+
+
+ // 画像2
+ _tobin_filter.doFilter(_raster, _binraster1);
+ this._bimg2.drawImage(_binraster1);
+ this.getGraphics().drawImage(this._bimg2, 32, 32 + 240, 320 + 32, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+ // 画像3
+ NyARLabelingImage limage = new NyARLabelingImage(320, 240);
+ NyARLabeling_ARToolKit labeling = new NyARLabeling_ARToolKit();
+ labeling.labeling(_binraster1,limage);
+ this._bimg.drawImage(this._gsraster1);
+
+ NyARSquareStack stack = new NyARSquareStack(100);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void startCapture()
+ {
+ try {
+ capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ VisualTest mainwin = new VisualTest();
+ mainwin.setVisible(true);
+ mainwin.startCapture();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry path="" kind="src"/>\r
+ <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>\r
+ <classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="C:/Program Files/Java/Java3D/1.5.1/lib/ext/j3dcore.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/Java/Java3D/1.5.1/lib/ext/j3dutils.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/Java/Java3D/1.5.1/lib/ext/vecmath.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>\r
+ <classpathentry path="/NyARToolkit.utils.jmf" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="" kind="output"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolkit.utils.java3d</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit Java3D utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.java3d.utils;\r
+\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+\r
+import javax.media.j3d.Transform3D;\r
+/**\r
+ * NyARParamにJava3D向け関数を追加したもの\r
+ */\r
+public class J3dNyARParam extends NyARParam\r
+{\r
+ private double view_distance_min = 0.01;//1cm~10.0m\r
+\r
+ private double view_distance_max = 10.0;\r
+\r
+ private Transform3D m_projection = null;\r
+\r
+ /**\r
+ * 視体積の近い方をメートルで指定\r
+ * @param i_new_value\r
+ */\r
+ public void setViewDistanceMin(double i_new_value)\r
+ {\r
+ m_projection = null;//キャッシュ済変数初期化\r
+ view_distance_min = i_new_value;\r
+ }\r
+\r
+ /**\r
+ * 視体積の遠い方をメートルで指定\r
+ * @param i_new_value\r
+ */\r
+ public void setViewDistanceMax(double i_new_value)\r
+ {\r
+ m_projection = null;//キャッシュ済変数初期化\r
+ view_distance_max = i_new_value;\r
+ }\r
+\r
+ /**\r
+ * void arglCameraFrustumRH(const ARParam *cparam, const double focalmin, const double focalmax, GLdouble m_projection[16])\r
+ * 関数の置き換え\r
+ * @param focalmin\r
+ * @param focalmax\r
+ * @return\r
+ */\r
+ public Transform3D getCameraTransform()\r
+ {\r
+ //既に値がキャッシュされていたらそれを使う\r
+ if (m_projection != null) {\r
+ return m_projection;\r
+ }\r
+ //無ければ計算\r
+\r
+ NyARMat trans_mat = new NyARMat(3, 4);\r
+ NyARMat icpara_mat = new NyARMat(3, 4);\r
+ double[][] p = new double[3][3], q = new double[4][4];\r
+ double width, height;\r
+ int i, j;\r
+\r
+ width = this._screen_size.w;\r
+ height = this._screen_size.h;\r
+\r
+ this.getPerspectiveProjectionMatrix().decompMat(icpara_mat, trans_mat);\r
+\r
+ double[][] icpara = icpara_mat.getArray();\r
+ double[][] trans = trans_mat.getArray();\r
+ for (i = 0; i < 4; i++) {\r
+ icpara[1][i] = (height - 1) * (icpara[2][i]) - icpara[1][i];\r
+ }\r
+\r
+ for (i = 0; i < 3; i++) {\r
+ for (j = 0; j < 3; j++) {\r
+ p[i][j] = icpara[i][j] / icpara[2][2];\r
+ }\r
+ }\r
+ //p[0][0],p[1][1]=n\r
+ //p[0][2],p[1][2]=t+b\r
+\r
+ //Projectionの計算\r
+ q[0][0] = (2.0 * p[0][0] / (width - 1));\r
+ q[0][1] = (2.0 * p[0][1] / (width - 1));\r
+ q[0][2] = -((2.0 * p[0][2] / (width - 1)) - 1.0);\r
+ q[0][3] = 0.0;\r
+\r
+ q[1][0] = 0.0;\r
+ q[1][1] = -(2.0 * p[1][1] / (height - 1));\r
+ q[1][2] = -((2.0 * p[1][2] / (height - 1)) - 1.0);\r
+ q[1][3] = 0.0;\r
+\r
+ q[2][0] = 0.0;\r
+ q[2][1] = 0.0;\r
+ q[2][2] = (view_distance_max + view_distance_min) / (view_distance_min - view_distance_max);\r
+ q[2][3] = 2.0 * view_distance_max * view_distance_min / (view_distance_min - view_distance_max);\r
+\r
+ q[3][0] = 0.0;\r
+ q[3][1] = 0.0;\r
+ q[3][2] = -1.0;\r
+ q[3][3] = 0.0;\r
+\r
+ q[2][2] = q[2][2] * -1;\r
+ q[2][3] = q[2][3] * -1;\r
+\r
+ double[] tmp_projection = new double[16];\r
+ for (i = 0; i < 4; i++) { // Row.\r
+ // First 3 columns of the current row.\r
+ for (j = 0; j < 3; j++) { // Column.\r
+ tmp_projection[i + j * 4] = (q[i][0] * trans[0][j] + q[i][1] * trans[1][j] + q[i][2] * trans[2][j]);\r
+ }\r
+ // Fourth column of the current row.\r
+ tmp_projection[i + 3 * 4] = q[i][0] * trans[0][3] + q[i][1] * trans[1][3] + q[i][2] * trans[2][3] + q[i][3];\r
+ }\r
+ m_projection = new Transform3D(tmp_projection);\r
+ m_projection.transpose();\r
+ return m_projection;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit Java3D utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.java3d.utils;\r
+\r
+import java.awt.image.*;\r
+\r
+import javax.media.format.VideoFormat;\r
+import javax.media.j3d.ImageComponent;\r
+import javax.media.j3d.ImageComponent2D;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+/**\r
+ * \r
+ * このクラスは、Java3Dと互換性のあるNyARToolkitのラスタイメージを保持します。\r
+ *\r
+ */\r
+public class J3dNyARRaster_RGB extends JmfNyARRaster_RGB\r
+{\r
+ private ImageComponent2D imc2d;\r
+\r
+ private byte[] i2d_buf;\r
+\r
+ private BufferedImage bufferd_image;\r
+\r
+ /**\r
+ * JMFのキャプチャ画像をこのクラスのBufferedImageにコピーします。\r
+ * @param i_buffer\r
+ * 画像の格納されたバッファを指定して下さい。\r
+ * 画像サイズはコンストラクタで与えたパラメタと同じサイズである必要があります。\r
+ */\r
+ public void setBuffer(javax.media.Buffer i_buffer) throws NyARException\r
+ {\r
+ this._reader.changeBuffer(i_buffer);\r
+ synchronized (this){\r
+ //キャプチャデータをi2dのバッファにコピーする。\r
+ //現在はJmfNyARRaster_RGBでRGB画像がノーマライズされているので、\r
+ //ここでもう一度flipする。(これ省略したいなあ…。)\r
+ byte[] src=(byte[])this._reader.getBuffer();\r
+ final int length = this._size.w * 3;\r
+ int src_idx = 0;\r
+ int dest_idx = (this._size.h - 1) * length; \r
+ for (int i = 0; i < this._size.h; i++) {\r
+ System.arraycopy(src,src_idx, this.i2d_buf, dest_idx, length);\r
+ src_idx += length;\r
+ dest_idx -= length;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+\r
+ public J3dNyARRaster_RGB(NyARParam i_cparam,VideoFormat i_format) throws NyARException\r
+ {\r
+ super(i_cparam.getScreenSize(),i_format);\r
+ //bufferdimageの種類を決める\r
+ if(this._reader.getBufferType()!=INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24){\r
+ throw new NyARException();\r
+ }\r
+ //RGBのラスタを作る。\r
+ this.bufferd_image = new BufferedImage(this._size.w, this._size.h, BufferedImage.TYPE_3BYTE_BGR);\r
+ i2d_buf = ((DataBufferByte) bufferd_image.getRaster().getDataBuffer()).getData();\r
+ this.imc2d = new ImageComponent2D(ImageComponent2D.FORMAT_RGB, this.bufferd_image, true, true);\r
+ imc2d.setCapability(ImageComponent.ALLOW_IMAGE_WRITE);\r
+ }\r
+\r
+ /**\r
+ * 自身の格納しているImageComponent2Dオブジェクトを作り直します。\r
+ * Java3D1.5がDirectXで動いた(らしいとき)に、ImageComponent2Dのインスタンス\r
+ * IDが異ならないと、Behavior内でイメージの更新を通知できない事象に対応するために実装してあります。\r
+ * Behavior内でgetImageComponent2()関数を実行する直前に呼び出すことで、この事象を回避することができます。\r
+ * \r
+ */\r
+ public void renewImageComponent2D()\r
+ {\r
+ this.imc2d = new ImageComponent2D(ImageComponent2D.FORMAT_RGB, this.bufferd_image, true, true);\r
+ this.imc2d.setCapability(ImageComponent.ALLOW_IMAGE_WRITE);\r
+ }\r
+\r
+ public ImageComponent2D getImageComponent2D()\r
+ {\r
+ return this.imc2d;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit Java3D utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.java3d.utils;\r
+\r
+import java.util.Enumeration;\r
+\r
+import javax.media.Buffer;\r
+import javax.media.j3d.*;\r
+import javax.vecmath.*;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * NyARToolkitと連動したBehaviorを返却するクラスです。\r
+ * 提供できるBehaviorは、BackgroundとTransformgroupです。\r
+ *\r
+ */\r
+public class NyARSingleMarkerBehaviorHolder implements JmfCaptureListener\r
+{\r
+ private NyARParam _cparam;\r
+\r
+ private JmfCaptureDevice _capture;\r
+\r
+ private J3dNyARRaster_RGB _nya_raster;//最大3スレッドで共有されるので、排他制御かけること。\r
+\r
+ private NyARSingleDetectMarker _nya;\r
+\r
+ //Behaviorホルダ\r
+ private NyARBehavior _nya_behavior;\r
+\r
+ public NyARSingleMarkerBehaviorHolder(NyARParam i_cparam, float i_rate, NyARCode i_ar_code, double i_marker_width) throws NyARException\r
+ {\r
+ this._nya_behavior = null;\r
+ final NyARIntSize scr_size = i_cparam.getScreenSize();\r
+ this._cparam = i_cparam;\r
+ //キャプチャの準備\r
+ JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();\r
+ this._capture=devlist.getDevice(0);\r
+ this._capture.setCaptureFormat(scr_size.w, scr_size.h,15f);\r
+ this._capture.setOnCapture(this); \r
+ this._nya_raster = new J3dNyARRaster_RGB(this._cparam,this._capture.getCaptureFormat());\r
+ this._nya = new NyARSingleDetectMarker(this._cparam, i_ar_code, i_marker_width,this._nya_raster.getBufferReader().getBufferType());\r
+ this._nya_behavior = new NyARBehavior(this._nya, this._nya_raster, i_rate);\r
+ }\r
+\r
+ public Behavior getBehavior()\r
+ {\r
+ return this._nya_behavior;\r
+ }\r
+\r
+ /**\r
+ * i_back_groundにキャプチャ画像を転送するようにBehaviorを設定します。\r
+ * i_back_groungはALLOW_IMAGE_WRITE属性を持つものである必要があります。\r
+ * @param i_back_groung\r
+ * @return\r
+ */\r
+ public void setBackGround(Background i_back_ground)\r
+ {\r
+ //コール先で排他制御\r
+ this._nya_behavior.setRelatedBackGround(i_back_ground);\r
+ }\r
+\r
+ /**\r
+ * i_trgroupの座標系をマーカーにあわせるようにBehaviorを設定します。\r
+ *\r
+ */\r
+ public void setTransformGroup(TransformGroup i_trgroup)\r
+ {\r
+ //コール先で排他制御\r
+ this._nya_behavior.setRelatedTransformGroup(i_trgroup);\r
+ }\r
+\r
+ /**\r
+ * 座標系再計算後に呼び出されるリスナです。\r
+ * @param i_listener\r
+ */\r
+ public void setUpdateListener(NyARSingleMarkerBehaviorListener i_listener)\r
+ {\r
+ //コール先で排他制御\r
+ this._nya_behavior.setUpdateListener(i_listener);\r
+ }\r
+\r
+ /**\r
+ * ラスタを更新 コールバック関数だから呼んじゃらめえ\r
+ */\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+ synchronized (this._nya_raster) {\r
+ this._nya_raster.setBuffer(i_buffer);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void start() throws NyARException\r
+ {\r
+ //開始\r
+ this._capture.start();\r
+ }\r
+\r
+ public void stop()\r
+ {\r
+ this._capture.stop();\r
+ }\r
+}\r
+\r
+class NyARBehavior extends Behavior\r
+{\r
+ private NyARTransMatResult trans_mat_result = new NyARTransMatResult();\r
+\r
+ private NyARSingleDetectMarker related_nya;\r
+\r
+ private TransformGroup trgroup;\r
+\r
+ private Background back_ground;\r
+\r
+ private J3dNyARRaster_RGB raster;\r
+\r
+ private WakeupCondition wakeup;\r
+\r
+ private NyARSingleMarkerBehaviorListener listener;\r
+\r
+ public void initialize()\r
+ {\r
+ wakeupOn(wakeup);\r
+ }\r
+\r
+ /**\r
+ * i_related_ic2dの内容で定期的にi_back_groundを更新するBehavior\r
+ * @param i_back_ground\r
+ * @param i_related_ic2d\r
+ */\r
+ public NyARBehavior(NyARSingleDetectMarker i_related_nya, J3dNyARRaster_RGB i_related_raster, float i_rate)\r
+ {\r
+ super();\r
+ wakeup = new WakeupOnElapsedTime((int) (1000 / i_rate));\r
+ related_nya = i_related_nya;\r
+ trgroup = null;\r
+ raster = i_related_raster;\r
+ back_ground = null;\r
+ listener = null;\r
+ this.setSchedulingBounds(new BoundingSphere(new Point3d(), 100.0));\r
+ }\r
+\r
+ public void setRelatedBackGround(Background i_back_ground)\r
+ {\r
+ synchronized (raster) {\r
+ back_ground = i_back_ground;\r
+ }\r
+ }\r
+\r
+ public void setRelatedTransformGroup(TransformGroup i_trgroup)\r
+ {\r
+ synchronized (raster) {\r
+ trgroup = i_trgroup;\r
+ }\r
+ }\r
+\r
+ public void setUpdateListener(NyARSingleMarkerBehaviorListener i_listener)\r
+ {\r
+ synchronized (raster) {\r
+ listener = i_listener;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * いわゆるイベントハンドラ\r
+ */\r
+ public void processStimulus(Enumeration criteria)\r
+ {\r
+ try {\r
+ synchronized (raster) {\r
+ Transform3D t3d = null;\r
+ boolean is_marker_exist = false;\r
+ if (back_ground != null) {\r
+ raster.renewImageComponent2D();/*DirectXモードのときの対策*/\r
+ back_ground.setImage(raster.getImageComponent2D());\r
+ }\r
+ if (raster.hasData()) {\r
+ is_marker_exist = related_nya.detectMarkerLite(raster, 100);\r
+ if (is_marker_exist)\r
+ {\r
+ final NyARTransMatResult src = this.trans_mat_result;\r
+ related_nya.getTransmationMatrix(src);\r
+// Matrix4d matrix = new Matrix4d(src.m00, -src.m10, -src.m20, 0, -src.m01, src.m11, src.m21, 0, -src.m02, src.m12, src.m22, 0, -src.m03, src.m13, src.m23, 1);\r
+ Matrix4d matrix = new Matrix4d(\r
+ -src.m00, -src.m10, src.m20, 0,\r
+ -src.m01, -src.m11, src.m21, 0,\r
+ -src.m02, -src.m12, src.m22, 0,\r
+ -src.m03,-src.m13, src.m23, 1);\r
+ matrix.transpose();\r
+ t3d = new Transform3D(matrix);\r
+ if (trgroup != null) {\r
+ trgroup.setTransform(t3d);\r
+ }\r
+ }\r
+ }\r
+ if (listener != null) {\r
+ listener.onUpdate(is_marker_exist, t3d);\r
+ }\r
+ }\r
+ wakeupOn(wakeup);\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit Java3D utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.java3d.utils;\r
+\r
+import javax.media.j3d.*;\r
+/**\r
+ * \r
+ * NyARToolkitのBehaviorのリスナ\r
+ *\r
+ */\r
+public interface NyARSingleMarkerBehaviorListener\r
+{\r
+ /**\r
+ * このリスナは、リスナにマーカーに連動してオブジェクトを操作するチャンスを与えます。\r
+ * リスナはNyARSingleMarkerBehavior関数内のprocessStimulus関数から呼び出されます。\r
+ * \r
+ * @param i_is_marker_exist\r
+ * マーカーが存在する場合true、存在しない場合、falseです。\r
+ * @param i_transform3d\r
+ * マーカーが存在する場合、その変換行列が指定されます。\r
+ * i_is_marker_existがtrueの時だけ有効です。\r
+ */\r
+ public void onUpdate(boolean i_is_marker_exist,Transform3D i_transform3d);\r
+}\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry path="" kind="src"/>\r
+ <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>\r
+ <classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>\r
+ <classpathentry path="" kind="output"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolkit.utils.jmf</name>\r
+ <comment></comment>\r
+ <projects>\r
+ <project>NyARToolKit</project>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JMF utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jmf.utils;\r
+\r
+import javax.media.*;\r
+import javax.media.protocol.*;\r
+import javax.media.control.*;\r
+import javax.media.format.*;\r
+import java.awt.*;\r
+import java.util.*;\r
+import javax.media.protocol.DataSource;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * 簡易JMFキャプチャクラス\r
+ * @deprecated このクラスは近い将来削除します。\r
+ * JmfCaptureDeviceList/JmfCaptureDeviceを使用してください。\r
+ * {@link #JmfCaptureDeviceList()}\r
+ *\r
+ */\r
+@Deprecated public class JmfCameraCapture\r
+{\r
+ private Dimension image_size;\r
+\r
+ private JmfCaptureListener capture_listener;\r
+\r
+ // private DataSource jmf_data_source;\r
+ private MonitorStream jmf_monitor_stream;\r
+\r
+ private Processor jmf_processor;\r
+\r
+ private VideoFormat jmf_video_format;\r
+\r
+ private Buffer read_buf = new Buffer();\r
+\r
+ public static final String PIXEL_FORMAT_RGB = "RGB";\r
+\r
+ public JmfCameraCapture(int i_width, int i_height, float i_rate, String i_pixcel_format)\r
+ {\r
+ String encoding = i_pixcel_format;// comboEncoding.getSelectedItem();\r
+ image_size = new Dimension(i_width, i_height);\r
+ jmf_video_format = new VideoFormat(encoding, image_size, Format.NOT_SPECIFIED, null, i_rate);\r
+ }\r
+\r
+ public Dimension getSize()\r
+ {\r
+ return image_size;\r
+ }\r
+\r
+ public javax.media.Buffer readBuffer() throws NyARException\r
+ {\r
+ if (jmf_monitor_stream == null) {\r
+ throw new NyARException();\r
+ }\r
+ try {\r
+ jmf_monitor_stream.read(read_buf);\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ return read_buf;\r
+ }\r
+\r
+ public void setCaptureListener(JmfCaptureListener i_listener) throws NyARException\r
+ {\r
+ if (jmf_processor != null)\r
+ {\r
+ throw new NyARException();\r
+ }\r
+ capture_listener = i_listener;\r
+\r
+ }\r
+\r
+ public void start() throws NyARException\r
+ {\r
+\r
+ DataSource ds = getCaptureDS(jmf_video_format);\r
+ VideoFormat[] formats = new VideoFormat[] { new VideoFormat(null) };\r
+ ProcessorModel pm = new ProcessorModel(ds, formats, null);// ,\r
+ // formats,\r
+ // ftd);\r
+ Processor processor;\r
+ try {\r
+ processor = Manager.createRealizedProcessor(pm);\r
+ } catch (Exception e) {\r
+ // Make sure the capture devices are released\r
+ ds.disconnect();\r
+ throw new NyARException(e);\r
+ }\r
+ // Get the monitor control:\r
+ // Since there are more than one MonitorControl objects\r
+ // exported by the DataSource, we get the specific one\r
+ // that is also the MonitorStream object.\r
+ jmf_monitor_stream = (MonitorStream) ds.getControl("jmfsample.MonitorStream");\r
+ jmf_monitor_stream.setCaptureListener(capture_listener);\r
+ // jmf_data_source=ds;\r
+ jmf_processor = processor;\r
+ jmf_processor.start();\r
+ }\r
+\r
+ public void stop()\r
+ {\r
+ jmf_processor.stop();\r
+ jmf_processor.close();\r
+ jmf_processor = null;\r
+\r
+ }\r
+\r
+ protected void finalize()\r
+ {\r
+ if (jmf_processor != null) {\r
+ jmf_processor.stop();\r
+ jmf_processor.close();\r
+ jmf_processor = null;\r
+ }\r
+ }\r
+\r
+ private static DataSource getCaptureDS(VideoFormat vf)\r
+ {\r
+ DataSource dsVideo = null;\r
+ DataSource ds = null;\r
+\r
+ // Create a capture DataSource for the video\r
+ // If there is no video capture device, then exit with null\r
+ if (vf != null) {\r
+ dsVideo = createDataSource(vf);\r
+ if (dsVideo == null)\r
+ return null;\r
+ }\r
+\r
+ // Create the monitoring datasource wrapper\r
+ if (dsVideo != null) {\r
+ dsVideo = new MonitorCDS(dsVideo);\r
+ return dsVideo;\r
+ }\r
+\r
+ // Merge the data sources, if both audio and video are available\r
+ try {\r
+ ds = Manager.createMergingDataSource(new DataSource[] { dsVideo });\r
+ } catch (IncompatibleSourceException ise) {\r
+ return null;\r
+ }\r
+\r
+ return ds;\r
+ }\r
+\r
+ private static DataSource createDataSource(Format format)\r
+ {\r
+ DataSource ds;\r
+ Vector devices;\r
+ CaptureDeviceInfo cdi;\r
+ MediaLocator ml;\r
+\r
+ // Find devices for format\r
+ devices = CaptureDeviceManager.getDeviceList(format);\r
+ if (devices.size() < 1) {\r
+ System.err.println("! No Devices for " + format);\r
+ return null;\r
+ }\r
+ // Pick the first device\r
+ cdi = (CaptureDeviceInfo) devices.elementAt(0);\r
+\r
+ ml = cdi.getLocator();\r
+\r
+ try {\r
+ ds = Manager.createDataSource(ml);\r
+ ds.connect();\r
+ if (ds instanceof CaptureDevice) {\r
+ setCaptureFormat((CaptureDevice) ds, format);\r
+ }\r
+ } catch (Exception e) {\r
+ System.err.println(e);\r
+ return null;\r
+ }\r
+ return ds;\r
+ }\r
+\r
+ private static void setCaptureFormat(CaptureDevice cdev, Format format)\r
+ {\r
+ FormatControl[] fcs = cdev.getFormatControls();\r
+ if (fcs.length < 1) {\r
+ return;\r
+ }\r
+ FormatControl fc = fcs[0];\r
+ Format[] formats = fc.getSupportedFormats();\r
+ for (int i = 0; i < formats.length; i++) {\r
+ if (formats[i].matches(format)) {\r
+ format = formats[i].intersects(format);\r
+ fc.setFormat(format);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package jp.nyatla.nyartoolkit.jmf.utils;\r
+\r
+import java.awt.Dimension;\r
+\r
+import javax.media.*;\r
+import javax.media.control.*;\r
+import javax.media.format.*;\r
+import javax.media.protocol.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+\r
+public class JmfCaptureDevice\r
+{\r
+ private JmfCaptureListener _capture_listener;\r
+ private MonitorStream _jmf_monitor_stream;\r
+ private Processor _jmf_processor;\r
+ private CaptureDeviceInfo _info;\r
+ private VideoFormat _capture_format;\r
+ private static final String[] _enc_str={"RGB","YUV"}; \r
+ public static final int PIXEL_FORMAT_RGB =0;// "RGB";\r
+ public static final int PIXEL_FORMAT_YUV =1;// "YUV";\r
+ public JmfCaptureDevice(CaptureDeviceInfo i_capinfo) throws NyARException\r
+ {\r
+ this._info = i_capinfo;\r
+ this._capture_format = null;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * サポートしているフォーマットの一覧を返します。\r
+ * @return\r
+ */\r
+ public Format[] getSupportFormats()\r
+ {\r
+ return this._info.getFormats();\r
+ }\r
+\r
+ public final VideoFormat getCaptureFormat()\r
+ {\r
+ return this._capture_format;\r
+ }\r
+\r
+ /**\r
+ * このキャプチャデバイスの提供する、i_index番目のフォーマットをキャプチャフォーマットに指定します。\r
+ * @param i_index\r
+ */\r
+ public void setCaptureFormat(int i_index)\r
+ {\r
+ this._capture_format = (VideoFormat)this._info.getFormats()[i_index];\r
+ return;\r
+ }\r
+ /**\r
+ * キャプチャ画像のフォーマットを指定した形式にしようと試みます。\r
+ * @param i_encode\r
+ * キャプチャする画像フォーマットを指定します。フォーマットはこのクラスに宣言される定数値を使ってください。\r
+ * @param i_size\r
+ * キャプチャ画像サイズを指定します。\r
+ * @param i_rate\r
+ * キャプチャレートをFPS単位で指定します。\r
+ * @return\r
+ * 指定に成功するとTRUEを返します。失敗するとFALSEを返します。\r
+ */ \r
+ protected boolean setCaptureFormat(int i_encode, Dimension i_size, float i_rate) throws NyARException\r
+ {\r
+ if (this._jmf_processor != null){\r
+ throw new NyARException();\r
+ }\r
+ Format[] formats = this._info.getFormats();\r
+ VideoFormat f = new VideoFormat(_enc_str[i_encode], i_size, Format.NOT_SPECIFIED, null, i_rate);\r
+ for (int i = 0; i < formats.length; i++){\r
+ if (formats[i].matches(f)) {\r
+ //[暫定実装]RGBの場合のみ、24bit-BGRAを強制する。他のフォーマットも取りたいときは要改造\r
+ //これはMacOSのJMF等で問題が出るかもしれない。問題が出たら教えて下さい。\r
+ if(formats[i] instanceof RGBFormat){\r
+ RGBFormat fmt_ref=(RGBFormat)formats[i];\r
+ if(fmt_ref.getBitsPerPixel()!=24 || fmt_ref.getBlueMask()!=1 || fmt_ref.getGreenMask()!=2 || fmt_ref.getRedMask()!=3){\r
+ continue;\r
+ }\r
+ }\r
+ f =(VideoFormat)formats[i].intersects(f);\r
+ this._capture_format = null;\r
+ this._capture_format = f;\r
+ return true;\r
+ }\r
+ }\r
+ //ない。\r
+ return false;\r
+ }\r
+ /**\r
+ * キャプチャ画像のエンコード、サイズ、レートを引数とするsetCaptureFormat関数です。\r
+ * @param i_encode\r
+ * PIXEL_FORMAT_XXXで定義される定数値を指定して下さい。\r
+ * @param i_size_x\r
+ * キャプチャする画像の横幅\r
+ * @param i_size_y\r
+ * キャプチャする画像の縦幅\r
+ * @param i_rate\r
+ * フレームレート\r
+ * @return\r
+ * 関数の実行結果を真偽値で返します。\r
+ * @throws NyARException\r
+ */ \r
+ public boolean setCaptureFormat(int i_encode,int i_size_x,int i_size_y, float i_rate) throws NyARException\r
+ {\r
+ return setCaptureFormat(i_encode,new Dimension(i_size_x,i_size_y),i_rate);\r
+ }\r
+ /**\r
+ * キャプチャ画像のサイズ、レートを引数とするsetCaptureFormat関数です。\r
+ * キャプチャ画像のエンコードは、RGB→YUVの順で検索します。\r
+ * @param i_size_x\r
+ * キャプチャする画像の横幅\r
+ * @param i_size_y\r
+ * キャプチャする画像の縦幅\r
+ * @param i_rate\r
+ * フレームレート\r
+ * @return\r
+ * 関数の実行結果を真偽値で返します。\r
+ * @throws NyARException\r
+ */\r
+ public boolean setCaptureFormat(int i_size_x,int i_size_y, float i_rate) throws NyARException\r
+ {\r
+ Dimension d=new Dimension(i_size_x,i_size_y);\r
+ if(setCaptureFormat(PIXEL_FORMAT_RGB,d,i_rate)){\r
+ return true;\r
+ }\r
+ if(setCaptureFormat(PIXEL_FORMAT_YUV,d,i_rate)){\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ \r
+ \r
+ /**\r
+ * 画像のキャプチャイベントを受信するリスナクラスを指定します。\r
+ * @param i_listener\r
+ * リスナークラス\r
+ * @throws NyARException\r
+ */\r
+ public void setOnCapture(JmfCaptureListener i_listener) throws NyARException\r
+ {\r
+ if (this._jmf_processor != null) {\r
+ throw new NyARException();\r
+ }\r
+ this._capture_listener = i_listener;\r
+ return;\r
+ }\r
+ /**\r
+ * キャプチャーを開始します。stop関数を呼び出すまでの間、setOnCaptureで指定したリスナークラスに、\r
+ * フォーマットで指定したキャプチャ画像が通知されます。\r
+ * @throws NyARException\r
+ */\r
+ public void start() throws NyARException\r
+ {\r
+ // startしていたらエラー\r
+ if (this._jmf_processor != null) {\r
+ throw new NyARException();\r
+ }\r
+ DataSource ds;\r
+ final MediaLocator ml = this._info.getLocator();\r
+ try {\r
+ ds = Manager.createDataSource(ml);\r
+ ds.connect();\r
+ // ここでフォーマットを作成\r
+ if (ds instanceof CaptureDevice) {\r
+ FormatControl[] fcs = ((CaptureDevice) ds).getFormatControls();\r
+ if (fcs.length < 1) {\r
+ return;\r
+ }\r
+ FormatControl fc = fcs[0];\r
+ fc.setFormat(this._capture_format);\r
+ }\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ try{\r
+ if(ds==null){\r
+ //Merge the data sources, if both audio and video are available\r
+ ds = Manager.createMergingDataSource(new DataSource[] { null }); \r
+ }else{\r
+ // Create the monitoring datasource wrapper\r
+ ds = new MonitorCDS(ds); \r
+ }\r
+ }catch(IncompatibleSourceException e){\r
+ throw new NyARException(e);\r
+ }\r
+ \r
+ // データソース完成\r
+ try {\r
+ // Merge the data sources, if both audio and video are available\r
+ VideoFormat[] formats = new VideoFormat[] { new VideoFormat(null) };\r
+ ProcessorModel pm = new ProcessorModel(ds, formats, null);// ,\r
+ Processor processor;\r
+ processor = Manager.createRealizedProcessor(pm);\r
+ this._jmf_monitor_stream = (MonitorStream) ds.getControl("jmfsample.MonitorStream");\r
+ this._jmf_monitor_stream.setCaptureListener(this._capture_listener);\r
+ this._jmf_processor = processor;\r
+ this._jmf_processor.start();\r
+ } catch (Exception e) {\r
+ ds.disconnect();\r
+ throw new NyARException(e);\r
+ }\r
+ return;\r
+ }\r
+\r
+ public void stop()\r
+ {\r
+ this._jmf_processor.stop();\r
+ this._jmf_processor.close();\r
+ this._jmf_processor = null;\r
+ return;\r
+ }\r
+ protected void finalize()\r
+ {\r
+ if (this._jmf_processor != null) {\r
+ this._jmf_processor.stop();\r
+ this._jmf_processor.close();\r
+ this._jmf_processor = null;\r
+ }\r
+ return;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package jp.nyatla.nyartoolkit.jmf.utils;\r
+\r
+import java.awt.Dimension;\r
+import java.util.Vector;\r
+\r
+import javax.media.CaptureDeviceInfo;\r
+import javax.media.CaptureDeviceManager;\r
+import javax.media.Format;\r
+import javax.media.format.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+\r
+\r
+\r
+/**\r
+ * JMFキャプチャデバイスのリストを保持します。\r
+ * 複数のカメラが接続された環境では、最も初めに認識したカメラの実がアクティブになるため、\r
+ * このクラスで実際に認識できるカメラは1個だけです。\r
+ *\r
+ */\r
+public class JmfCaptureDeviceList\r
+{\r
+ private Vector _devices;\r
+\r
+ public JmfCaptureDeviceList() throws NyARException\r
+ {\r
+ this._devices = (Vector) CaptureDeviceManager.getDeviceList(null).clone();\r
+ // ビデオソースのデバイスだけ残す\r
+ try {\r
+\r
+ for (int i = 0; i < this._devices.size();) {\r
+ CaptureDeviceInfo cdi = (CaptureDeviceInfo) this._devices.elementAt(i);\r
+ // VideoFormatもってるかな?\r
+ if (!isCaptureDevice(cdi)) {\r
+ this._devices.remove(i);\r
+ continue;\r
+ }\r
+ i++;\r
+ }\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * i_cdiがビデオキャプチャデバイスかを調べる。ようなことをする。\r
+ * \r
+ * @param i_cdi\r
+ * @return\r
+ */\r
+ private static boolean isCaptureDevice(CaptureDeviceInfo i_cdi)\r
+ {\r
+ Format[] fms = i_cdi.getFormats();\r
+ for (int i = 0; i < fms.length; i++) {\r
+ Format f = fms[i];\r
+ if (f instanceof VideoFormat) {\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * 使用できるキャプチャデバイスの数を数える\r
+ * @return\r
+ * キャプチャデバイスの数を返却する。\r
+ */\r
+ public int getCount()\r
+ {\r
+ return this._devices.size();\r
+ }\r
+ /**\r
+ * i_index番目のキャプチャデバイスを得る。\r
+ * @param i_index\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public JmfCaptureDevice getDevice(int i_index) throws NyARException\r
+ {\r
+ return new JmfCaptureDevice((CaptureDeviceInfo) this._devices.elementAt(i_index));\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ //テストケース\r
+ try {\r
+ JmfCaptureDeviceList j = new JmfCaptureDeviceList();\r
+ System.out.println(j.getCount());\r
+ JmfCaptureDevice d = j.getDevice(0);\r
+ d.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_RGB, new Dimension(320, 240), 15.0f);\r
+// YUVFormat f=(YUVFormat)d.getCaptureFormat();\r
+ d.start();\r
+ d.stop();\r
+\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ return;\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JMF utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jmf.utils;\r
+\r
+import javax.media.Buffer;\r
+/**\r
+ * JMF簡易キャプチャ用のリスナクラス\r
+ *\r
+ */\r
+public interface JmfCaptureListener{\r
+ public void onUpdateBuffer(Buffer i_buffer);\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JMF utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jmf.utils;\r
+\r
+import javax.media.format.*;\r
+import javax.media.*;\r
+import java.awt.Dimension;\r
+import com.sun.media.codec.video.colorspace.*;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+\r
+\r
+/**\r
+ * RGB24フォーマットのデータを扱うピクセルリーダ\r
+ */\r
+class NyARBufferReader_Reader_RGB24 extends NyARBufferReader_Reader\r
+{\r
+ protected boolean _is_flipped;\r
+ public NyARBufferReader_Reader_RGB24(RGBFormat i_input_format,NyARIntSize i_ref_size) throws NyARException\r
+ {\r
+ super(i_ref_size);\r
+ //ピクセルフォーマットを設定(現状は24bitRGBを受けつける。)\r
+ RGBFormat fm=(RGBFormat)i_input_format;\r
+ if(fm.getBitsPerPixel()!=24){\r
+ throw new NyARException();\r
+ }\r
+ int r=fm.getRedMask();\r
+ int b=fm.getBlueMask();\r
+ if(r==1 && b==3){\r
+ this._buf_type=BUFFERFORMAT_BYTE1D_R8G8B8_24;\r
+ }else if(r==3 && b==1){\r
+ this._buf_type=BUFFERFORMAT_BYTE1D_B8G8R8_24; \r
+ }else{\r
+ throw new NyARException();\r
+ }\r
+ //vertical反転の有無を確認\r
+ this._is_flipped=i_input_format.getFlipped()!=0?true:false;\r
+ this._ref_buf=new byte[i_ref_size.w*i_ref_size.h*3];\r
+ //RGBフォーマット\r
+ \r
+ return;\r
+ }\r
+ public void changeBuffer(javax.media.Buffer i_buffer)\r
+ {\r
+ //vertical反転が必要ならば、反転した画像を作成する。\r
+ byte[] src=(byte[])i_buffer.getData();\r
+ if(this._is_flipped){\r
+ final int length = this._ref_size.w * 3;\r
+ int src_idx = 0;\r
+ int dest_idx = (this._ref_size.h - 1) * length; \r
+ for (int i = 0; i < this._ref_size.h; i++) {\r
+ System.arraycopy(src,src_idx, this._ref_buf, dest_idx, length);\r
+ src_idx += length;\r
+ dest_idx -= length;\r
+ }\r
+ }else{\r
+ System.arraycopy(src,0,this._ref_buf,0,this._ref_buf.length);\r
+ this._ref_buf=(byte[])i_buffer.getData();\r
+ }\r
+ return;\r
+ }\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
+ {\r
+ int bp = (i_x + i_y * this._ref_size.w) * 3;\r
+ byte[] ref = this._ref_buf;\r
+ switch(this._buf_type){\r
+ case BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ o_rgb[0] = (ref[bp + 0] & 0xff);// R\r
+ o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[2] = (ref[bp + 2] & 0xff);// B\r
+ break;\r
+ case BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ o_rgb[0] = (ref[bp + 2] & 0xff);// B\r
+ o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[2] = (ref[bp + 0] & 0xff);// R\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ return;\r
+ }\r
+ public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
+ {\r
+ int width = this._ref_size.w;\r
+ byte[] ref = this._ref_buf;\r
+ int bp;\r
+ switch(this._buf_type){\r
+ case BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ bp = (i_x[i] + i_y[i] * width) * 3;\r
+ o_rgb[i * 3 + 0] = (ref[bp + 0] & 0xff);// R\r
+ o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[i * 3 + 2] = (ref[bp + 2] & 0xff);// B\r
+ }\r
+ break;\r
+ case BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ bp = (i_x[i] + i_y[i] * width) * 3;\r
+ o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// B\r
+ o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// R\r
+ }\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ return;\r
+ }\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * ソースがYUVフォーマットのデータをBGR24として扱うピクセルリーダ\r
+ * ソースデータをセットした時に変換します。\r
+ * (将来YUVをそのまま素通りさせるように書き換えるかも)\r
+ */\r
+class NyARBufferReader_Reader_YUV extends NyARBufferReader_Reader\r
+{\r
+ \r
+ private YUVToRGB _yuv2rgb;\r
+ private javax.media.Buffer _rgb_buf;\r
+ /**\r
+ * フォーマットアレイから、BGR24フォーマットを探す\r
+ * @param i_formats\r
+ * @return\r
+ */\r
+ private Format pickRGB24Format(Format[] i_formats)\r
+ {\r
+ for(int i=0;i<i_formats.length;i++){\r
+ RGBFormat f=(RGBFormat)i_formats[i];\r
+ if(f.getBitsPerPixel()!=24){\r
+ continue;\r
+ }\r
+ if(f.getRedMask()!=3 ||f.getGreenMask()!=2 ||f.getBlueMask()!=1 || f.getFlipped()!=0)\r
+ {\r
+ continue;\r
+ }\r
+ return f;\r
+ }\r
+ return null;\r
+ }\r
+ public NyARBufferReader_Reader_YUV(YUVFormat i_input_format,NyARIntSize i_ref_size) throws NyARException\r
+ {\r
+ super(i_ref_size,BUFFERFORMAT_BYTE1D_B8G8R8_24);\r
+ this._yuv2rgb=new YUVToRGB();\r
+ this._rgb_buf=new javax.media.Buffer();\r
+ this._ref_buf=null;\r
+ //24bit-BGRフォーマットのものを探す\r
+ Format output_format=pickRGB24Format(this._yuv2rgb.getSupportedOutputFormats(i_input_format));\r
+ if(output_format==null){\r
+ throw new NyARException();\r
+ }\r
+ this._yuv2rgb.setInputFormat(i_input_format);\r
+ this._yuv2rgb.setOutputFormat(output_format);\r
+ try{\r
+ this._yuv2rgb.open();\r
+ }catch(Exception e){\r
+ throw new NyARException();\r
+ }\r
+ return;\r
+ }\r
+ public void changeBuffer(javax.media.Buffer i_buffer)\r
+ {\r
+ //エラー出した時のトラップ\r
+ if(this._yuv2rgb.process(i_buffer, this._rgb_buf)!=YUVToRGB.BUFFER_PROCESSED_OK){\r
+ System.err.println("YUVToRGB.process error:");\r
+ }\r
+ this._ref_buf=(byte[])this._rgb_buf.getData();\r
+ return;\r
+ }\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
+ {\r
+ //IN :BGRBGR\r
+ // :012012\r
+ final int bp = (i_x + i_y * this._ref_size.w) * 3;\r
+ final byte[] ref = this._ref_buf;\r
+ o_rgb[0] = (ref[bp + 2] & 0xff);// R\r
+ o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[2] = (ref[bp + 0] & 0xff);// B\r
+ return;\r
+ }\r
+ public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
+ {\r
+ int bp;\r
+ final int width = this._ref_size.w;\r
+ final byte[] ref = this._ref_buf;\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ bp = (i_x[i] + i_y[i] * width) * 3;\r
+ o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// R\r
+ o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// B\r
+ }\r
+ return;\r
+ }\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ \r
+}\r
+\r
+\r
+/**\r
+ * \r
+ * RGB形式のJMFバッファをラップするNyARRasterです。\r
+ * JMFから得たラスタデータのピクセル並び順を考慮します。\r
+ *\r
+ */\r
+public class JmfNyARRaster_RGB extends NyARRgbRaster_BasicClass\r
+{\r
+\r
+ protected NyARBufferReader_Reader _reader;\r
+ /**\r
+ * i_formatに一致する画素フォーマットの\r
+ * @param i_size\r
+ * @param i_format\r
+ * @throws NyARException\r
+ */\r
+\r
+\r
+ public JmfNyARRaster_RGB(NyARIntSize i_ref_size,VideoFormat i_format) throws NyARException\r
+ {\r
+ super(new NyARIntSize(i_ref_size)); \r
+ this._reader = createReader(i_format);\r
+ }\r
+ public JmfNyARRaster_RGB(int i_width,int i_height,VideoFormat i_format) throws NyARException\r
+ {\r
+ super(new NyARIntSize(i_width,i_height));\r
+ this._reader = createReader(i_format);\r
+ }\r
+ \r
+ /**\r
+ * フォーマットを解析して、マッチするリーダオブジェクトを返します。\r
+ * @param i_fmt\r
+ * ビデオフォーマットを指定します。\r
+ * @return\r
+ * リーダオブジェクト\r
+ * @throws NyARException\r
+ */\r
+ private NyARBufferReader_Reader createReader(VideoFormat i_fmt) throws NyARException\r
+ {\r
+ // データサイズの確認\r
+ final Dimension s = i_fmt.getSize();\r
+ if (!this._size.isEqualSize(s.width, s.height)) {\r
+ throw new NyARException();\r
+ }\r
+ // データ配列の確認\r
+ if(i_fmt instanceof YUVFormat){\r
+ //YUVフォーマット\r
+ return new NyARBufferReader_Reader_YUV((YUVFormat)i_fmt,this._size); \r
+ }else if(i_fmt instanceof RGBFormat){\r
+ //RGBフォーマット\r
+ return new NyARBufferReader_Reader_RGB24((RGBFormat)i_fmt,this._size);\r
+ }else{\r
+ throw new NyARException();\r
+ }\r
+ }\r
+\r
+ /**\r
+ * javax.media.Bufferを分析して、その分析結果をNyARRasterに適合する形で保持します。\r
+ * 関数実行後に外部でi_bufferの内容変更した場合には、再度setBuffer関数を呼び出してください。\r
+ * この関数を実行すると、getRgbPixelReaderで取得したReaderのプロパティが変化することがあります。\r
+ * @param i_buffer\r
+ * RGB形式のデータを格納したjavax.media.Bufferオブジェクトを指定してください。\r
+ * @return i_bufferをラップしたオブジェクトを返します。\r
+ * @throws NyARException\r
+ */\r
+ public void setBuffer(javax.media.Buffer i_buffer) throws NyARException\r
+ {\r
+ this._reader.changeBuffer(i_buffer);\r
+ return;\r
+ }\r
+ /**\r
+ * データを持っているかを返します。\r
+ * @return\r
+ */\r
+ public boolean hasData()\r
+ {\r
+ return this._reader._ref_buf != null;\r
+ }\r
+ public INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._reader;\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._reader;\r
+ }\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/*
+ * Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
+ * modify and redistribute this software in source and binary code form,
+ * provided that i) this copyright notice and license appear on all copies of
+ * the software; and ii) Licensee does not utilize the software in a manner
+ * which is disparaging to Sun.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
+ * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
+ * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
+ * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
+ * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * This software is not designed or intended for use in on-line control of
+ * aircraft, air traffic, aircraft navigation or aircraft communications; or in
+ * the design, construction, operation or maintenance of any nuclear
+ * facility. Licensee represents and warrants that it will not use or
+ * redistribute the Software for such purposes.
+ */
+package jp.nyatla.nyartoolkit.jmf.utils;
+
+import javax.media.*;
+import javax.media.protocol.*;
+import javax.media.control.*;
+
+import java.io.IOException;
+
+public class MonitorCDS extends PushBufferDataSource
+{
+
+ private PushBufferDataSource delegate = null;
+
+ private PushBufferStream[] delStreams = null;
+
+ private MonitorStream monitorStream = null;
+
+ private PushBufferStream[] monitorStreams = null;
+
+ boolean delStarted = false; // variable used by MonitorStream also
+
+ private Control[] controls;
+
+ public MonitorCDS(DataSource ds)
+ {
+ // Get the stream from the actual datasource
+ // and create a MonitorStream from it
+ // Export the MonitorControl interface of the MonitorStream
+ if (ds instanceof PushBufferDataSource) {
+ delegate = (PushBufferDataSource) ds;
+ delStreams = delegate.getStreams();
+ monitorStream = new MonitorStream(delStreams[0], this);
+ monitorStreams = new PushBufferStream[] { monitorStream };
+ }
+ }
+
+ public Object[] getControls()
+ {
+ return controls;
+ }
+
+ public Object getControl(String value)
+ {
+ if (value.equals("jmfsample.MonitorStream") || value.equals("javax.media.control.MonitorControl")){
+ return monitorStream;
+ }else{
+ return null;
+ }
+ }
+
+ public javax.media.CaptureDeviceInfo getCaptureDeviceInfo()
+ {
+ return ((CaptureDevice) delegate).getCaptureDeviceInfo();
+ }
+
+ public FormatControl[] getFormatControls()
+ {
+ return ((CaptureDevice) delegate).getFormatControls();
+ }
+
+ public String getContentType()
+ {
+ return delegate.getContentType();
+ }
+
+ public void connect() throws IOException
+ {
+ if (delegate == null)
+ throw new IOException("Incompatible DataSource");
+ // Delegate is already connected
+ }
+
+ public void disconnect()
+ {
+ monitorStream.setEnabled(false);
+ delegate.disconnect();
+ }
+
+ public synchronized void start() throws IOException
+ {
+ startDelegate();
+ delStarted = true;
+ }
+
+ public synchronized void stop() throws IOException
+ {
+ if (!monitorStream.isEnabled()) {
+ stopDelegate();
+ }
+ delStarted = false;
+ }
+
+ public Time getDuration()
+ {
+ return delegate.getDuration();
+ }
+
+ public PushBufferStream[] getStreams()
+ {
+ return monitorStreams;
+ }
+
+ void startDelegate() throws IOException
+ {
+ delegate.start();
+ }
+
+ void stopDelegate() throws IOException
+ {
+ delegate.stop();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
+ * modify and redistribute this software in source and binary code form,
+ * provided that i) this copyright notice and license appear on all copies of
+ * the software; and ii) Licensee does not utilize the software in a manner
+ * which is disparaging to Sun.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
+ * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
+ * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
+ * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
+ * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * This software is not designed or intended for use in on-line control of
+ * aircraft, air traffic, aircraft navigation or aircraft communications; or in
+ * the design, construction, operation or maintenance of any nuclear
+ * facility. Licensee represents and warrants that it will not use or
+ * redistribute the Software for such purposes.
+ */
+package jp.nyatla.nyartoolkit.jmf.utils;
+
+import javax.media.*;
+import javax.media.protocol.*;
+
+import javax.media.util.BufferToImage;
+import java.io.IOException;
+import java.awt.*;
+
+public class MonitorStream implements PushBufferStream, BufferTransferHandler
+{
+
+ JmfCaptureListener img_listener;
+
+ PushBufferStream actual = null;
+
+ boolean dataAvailable = false;
+
+ boolean terminate = false;
+
+ boolean enabled = false;
+
+ Object bufferLock = new Object();
+
+ Buffer cbuffer = new Buffer();
+
+ BufferTransferHandler transferHandler = null;
+
+ Component component = null;
+
+ MonitorCDS cds;
+
+ BufferToImage bti = null;
+
+ MonitorStream(PushBufferStream actual, MonitorCDS cds)
+ {
+ this.actual = actual;
+ actual.setTransferHandler(this);
+ this.cds = cds;
+ }
+
+ public javax.media.Format getFormat()
+ {
+ return actual.getFormat();
+ }
+
+ /**
+ * 非同期READ
+ */
+ public void read(Buffer buffer) throws IOException
+ {
+ // Wait for data to be available
+ // Doesn't get used much because the transferData
+ // call is made when data IS available. And most
+ // Processors/Players read the data in the same
+ // thread that called transferData, although that's
+ // not a safe assumption to make
+ if (!dataAvailable) {
+ synchronized (bufferLock) {
+ while (!dataAvailable && !terminate) {
+ try {
+ bufferLock.wait(100);
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+ }
+
+ if (dataAvailable) {
+ synchronized (bufferLock) {
+ // Copy the buffer attributes, but swap the data
+ // attributes so that no extra copy is made.
+ buffer.copy(cbuffer, true);
+ //dataAvailable = false;
+ }
+ }
+ // return;
+ }
+
+ public void setCaptureListener(JmfCaptureListener i_listener)
+ {
+ img_listener = i_listener;
+ }
+
+ public void transferData(PushBufferStream pbs)
+ {
+ // Get the data from the original source stream
+ synchronized (bufferLock) {
+ try {
+ pbs.read(cbuffer);
+ } catch (IOException ioe) {
+ return;
+ }
+ dataAvailable = true;
+ bufferLock.notifyAll();
+ }
+ if (img_listener != null) {
+ img_listener.onUpdateBuffer(cbuffer);
+ }
+
+ // Maybe synchronize this with setTransferHandler() ?
+ if (transferHandler != null && cds.delStarted)
+ transferHandler.transferData(this);
+ }
+
+ public void setTransferHandler(BufferTransferHandler transferHandler)
+ {
+ this.transferHandler = transferHandler;
+ }
+
+ public boolean setEnabled(boolean value)
+ {
+ enabled = value;
+ if (value == false) {
+ if (!cds.delStarted) {
+ try {
+ cds.stopDelegate();
+ } catch (IOException ioe) {
+ }
+ }
+ } else {
+ // Start the capture datasource if the monitor is enabled
+ try {
+ cds.startDelegate();
+ } catch (IOException ioe) {
+ }
+ }
+ return enabled;
+ }
+
+ public boolean isEnabled()
+ {
+ return enabled;
+ }
+
+ public float setPreviewFrameRate(float rate)
+ {
+ System.err.println("TODO");
+ return rate;
+ }
+
+ public ContentDescriptor getContentDescriptor()
+ {
+ return actual.getContentDescriptor();
+ }
+
+ public long getContentLength()
+ {
+ return actual.getContentLength();
+ }
+
+ public boolean endOfStream()
+ {
+ return actual.endOfStream();
+ }
+
+ public Object[] getControls()
+ {
+ return new Object[0];
+ }
+
+ public Object getControl(String str)
+ {
+ return null;
+ }
+
+}
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JMF utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jmf.utils;\r
+\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARRgbPixelReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public abstract class NyARBufferReader_Reader implements INyARRgbPixelReader,INyARBufferReader\r
+{\r
+ protected byte[] _ref_buf;\r
+ protected NyARIntSize _ref_size;\r
+ protected int _buf_type;\r
+ protected NyARBufferReader_Reader(NyARIntSize i_ref_size,int i_buf_type)\r
+ {\r
+ this._ref_size =i_ref_size;\r
+ this._buf_type=i_buf_type;\r
+ return;\r
+ }\r
+ protected NyARBufferReader_Reader(NyARIntSize i_ref_size)\r
+ {\r
+ this._ref_size =i_ref_size;\r
+ return;\r
+ }\r
+ final public Object getBuffer()\r
+ {\r
+ return this._ref_buf;\r
+ }\r
+ final public int getBufferType()\r
+ {\r
+ return this._buf_type;\r
+ }\r
+ final public boolean isEqualBufferType(int i_type_value)\r
+ {\r
+ return this._buf_type==i_type_value;\r
+ }\r
+ public abstract void changeBuffer(javax.media.Buffer i_buffer);\r
+\r
+}\r
--- /dev/null
+/*
+ * PROJECT: NyARToolkit JMF utilities.
+ * --------------------------------------------------------------------------------
+ * The MIT License
+ * Copyright (c) 2008 nyatla
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+package jp.nyatla.nyartoolkit.jmf.utils.sample;
+
+import javax.media.*;
+
+import javax.media.util.BufferToImage;
+import javax.media.format.*;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
+
+import java.awt.*;
+
+/**
+ * VFMキャプチャテストプログラム
+ */
+public class JmfCaptureTest extends Frame implements JmfCaptureListener
+{
+ private static final long serialVersionUID = -2110888320986446576L;
+ private JmfCaptureDevice _capture;
+ public JmfCaptureTest() throws NyARException
+ {
+ setTitle("JmfCaptureTest");
+ setBounds(0, 0, 320 + 64, 240 + 64);
+ JmfCaptureDeviceList dl=new JmfCaptureDeviceList();
+ this._capture=dl.getDevice(0);
+ if(!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_RGB,320,240,30.0f)){
+ if(!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_YUV,320,240,30.0f)){
+ throw new NyARException("キャプチャフォーマットが見つかりません。");
+ }
+ }
+ this._capture.setOnCapture(this);
+ }
+
+
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+ BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+ Image img = b2i.createImage(i_buffer);
+ Graphics g = getGraphics();
+ g.drawImage(img, 32, 32, this);
+ }
+
+ private void startCapture()
+ {
+ try {
+ this._capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ JmfCaptureTest mainwin = new JmfCaptureTest();
+ mainwin.setVisible(true);
+ mainwin.startCapture();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry path="" kind="src"/>\r
+ <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>\r
+ <classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="/NyARToolkit.utils.jmf" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/Java/jre1.6.0_03/lib/gluegen-rt.jar" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/Java/jre1.6.0_03/lib/jogl.jar" kind="lib"/>\r
+ <classpathentry path="" kind="output"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolkit.utils.jogl</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JOGL utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jogl.utils;\r
+\r
+\r
+import javax.media.opengl.GL;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import javax.media.format.*;\r
+\r
+/**\r
+ * NyARRaster_RGBにOpenGL用のデータ変換機能を追加したものです。\r
+ */\r
+public class GLNyARRaster_RGB extends JmfNyARRaster_RGB\r
+{\r
+ private int _gl_flag;\r
+ /**\r
+ * コンストラクタです。i_formatを取り込めるi_paramのサイズパラメタを持つ\r
+ * ラスタオブジェクトを作成します。\r
+ * @param i_param\r
+ * カメラパラメタを指定します。コンストラクタは、画面サイズ以外のパラメタを見ていません。\r
+ * @param i_format\r
+ * キャプチャ画像のピクセルフォーマットを指定します。\r
+ * @throws NyARException\r
+ */\r
+ public GLNyARRaster_RGB(NyARParam i_param,VideoFormat i_format) throws NyARException\r
+ {\r
+ super(i_param.getScreenSize(),i_format);\r
+ switch(this._reader.getBufferType()){\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ this._gl_flag = GL.GL_BGR;\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ this._gl_flag = GL.GL_RGB;\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * RGBバイト配列への参照値を返します。\r
+ * バッファの並び順は、getGLPixelFlagが返すデータ順で格納されています。\r
+ * @return\r
+ * RGBバイト配列の参照値です。\r
+ */\r
+ public byte[] getGLRgbArray()\r
+ {\r
+ return (byte[])this._reader.getBuffer();\r
+ }\r
+\r
+ /**\r
+ * OpenGLの描画フラグを返します。\r
+ * この値は、RGBバッファのバイト並びタイプです。\r
+ * @return\r
+ * GL.GL_BGR等の、RGBバイト配列の形式を表す値です。\r
+ */\r
+ public int getGLPixelFlag()\r
+ {\r
+ return this._gl_flag;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JOGL utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jogl.utils;\r
+\r
+import java.nio.*;\r
+import javax.media.opengl.GL;\r
+import javax.media.opengl.glu.GLU;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * NyARToolkit用のJOGL支援関数群\r
+ */\r
+public class NyARGLUtil\r
+{\r
+ private javax.media.opengl.GL _gl;\r
+\r
+ private javax.media.opengl.glu.GLU _glu;\r
+\r
+ public NyARGLUtil(javax.media.opengl.GL i_gl)\r
+ {\r
+ this._gl = i_gl;\r
+ this._glu = new GLU();\r
+ }\r
+\r
+ /**\r
+ * GLNyARRaster_RGBをバックグラウンドに書き出す。\r
+ * @param image\r
+ * @param zoom\r
+ */\r
+ public void drawBackGround(GLNyARRaster_RGB i_raster, double i_zoom)\r
+ {\r
+ IntBuffer texEnvModeSave = IntBuffer.allocate(1);\r
+ boolean lightingSave;\r
+ boolean depthTestSave;\r
+ javax.media.opengl.GL gl = this._gl;\r
+ final NyARIntSize rsize=i_raster.getSize();\r
+\r
+ // Prepare an orthographic projection, set camera position for 2D drawing, and save GL state.\r
+ gl.glGetTexEnviv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, texEnvModeSave); // Save GL texture environment mode.\r
+ if (texEnvModeSave.array()[0] != GL.GL_REPLACE) {\r
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);\r
+ }\r
+ lightingSave = gl.glIsEnabled(GL.GL_LIGHTING); // Save enabled state of lighting.\r
+ if (lightingSave == true) {\r
+ gl.glDisable(GL.GL_LIGHTING);\r
+ }\r
+ depthTestSave = gl.glIsEnabled(GL.GL_DEPTH_TEST); // Save enabled state of depth test.\r
+ if (depthTestSave == true) {\r
+ gl.glDisable(GL.GL_DEPTH_TEST);\r
+ }\r
+ gl.glMatrixMode(GL.GL_PROJECTION);\r
+ gl.glPushMatrix();\r
+ gl.glLoadIdentity();\r
+ _glu.gluOrtho2D(0.0,rsize.w, 0.0,rsize.h);\r
+ gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ gl.glPushMatrix();\r
+ gl.glLoadIdentity();\r
+ arglDispImageStateful(i_raster, i_zoom);\r
+\r
+ // Restore previous projection, camera position, and GL state.\r
+ gl.glMatrixMode(GL.GL_PROJECTION);\r
+ gl.glPopMatrix();\r
+ gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ gl.glPopMatrix();\r
+ if (depthTestSave) {\r
+ gl.glEnable(GL.GL_DEPTH_TEST); // Restore enabled state of depth test.\r
+ }\r
+ if (lightingSave) {\r
+ gl.glEnable(GL.GL_LIGHTING); // Restore enabled state of lighting.\r
+ }\r
+ if (texEnvModeSave.get(0) != GL.GL_REPLACE) {\r
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, texEnvModeSave.get(0)); // Restore GL texture environment mode.\r
+ }\r
+ gl.glEnd();\r
+ }\r
+\r
+ /**\r
+ * arglDispImageStateful関数モドキ\r
+ * @param image\r
+ * @param zoom\r
+ */\r
+ private void arglDispImageStateful(GLNyARRaster_RGB i_raster, double zoom)\r
+ {\r
+ javax.media.opengl.GL gl_ = this._gl;\r
+ final NyARIntSize rsize = i_raster.getSize();\r
+ float zoomf;\r
+ IntBuffer params = IntBuffer.allocate(4);\r
+ zoomf = (float) zoom;\r
+ gl_.glDisable(GL.GL_TEXTURE_2D);\r
+ gl_.glGetIntegerv(GL.GL_VIEWPORT, params);\r
+ gl_.glPixelZoom(zoomf * ((float) (params.get(2)) / (float) rsize.w), -zoomf * ((float) (params.get(3)) / (float) rsize.h));\r
+ gl_.glWindowPos2f(0.0f, (float) rsize.h);\r
+ gl_.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);\r
+ ByteBuffer buf = ByteBuffer.wrap(i_raster.getGLRgbArray());\r
+ gl_.glDrawPixels(rsize.w,rsize.h, i_raster.getGLPixelFlag(), GL.GL_UNSIGNED_BYTE, buf);\r
+ }\r
+ \r
+ private double view_scale_factor = 0.025;\r
+ private double view_distance_min = 0.1;//#define VIEW_DISTANCE_MIN 0.1 // Objects closer to the camera than this will not be displayed.\r
+ private double view_distance_max = 100.0;//#define VIEW_DISTANCE_MAX 100.0 // Objects further away from the camera than this will not be displayed.\r
+\r
+ public void setScaleFactor(double i_new_value)\r
+ {\r
+ this.view_scale_factor = i_new_value;\r
+ }\r
+\r
+ public void setViewDistanceMin(double i_new_value)\r
+ {\r
+ this.view_distance_min = i_new_value;\r
+ }\r
+\r
+ public void setViewDistanceMax(double i_new_value)\r
+ {\r
+ this.view_distance_max = i_new_value;\r
+ }\r
+\r
+ /**\r
+ * void arglCameraFrustumRH(const ARParam *cparam, const double focalmin, const double focalmax, GLdouble m_projection[16])\r
+ * 関数の置き換え\r
+ * NyARParamからOpenGLのProjectionを作成します。\r
+ * @param i_arparam\r
+ * @param o_gl_projection\r
+ * double[16]を指定して下さい。\r
+ */\r
+ public void toCameraFrustumRH(NyARParam i_arparam,double[] o_gl_projection)\r
+ {\r
+ NyARMat trans_mat = new NyARMat(3, 4);\r
+ NyARMat icpara_mat = new NyARMat(3, 4);\r
+ double[][] p = new double[3][3], q = new double[4][4];\r
+ int i, j;\r
+\r
+ final NyARIntSize size=i_arparam.getScreenSize();\r
+ final int width = size.w;\r
+ final int height = size.h;\r
+ \r
+ i_arparam.getPerspectiveProjectionMatrix().decompMat(icpara_mat, trans_mat);\r
+\r
+ double[][] icpara = icpara_mat.getArray();\r
+ double[][] trans = trans_mat.getArray();\r
+ for (i = 0; i < 4; i++) {\r
+ icpara[1][i] = (height - 1) * (icpara[2][i]) - icpara[1][i];\r
+ }\r
+\r
+ for (i = 0; i < 3; i++) {\r
+ for (j = 0; j < 3; j++) {\r
+ p[i][j] = icpara[i][j] / icpara[2][2];\r
+ }\r
+ }\r
+ q[0][0] = (2.0 * p[0][0] / (width - 1));\r
+ q[0][1] = (2.0 * p[0][1] / (width - 1));\r
+ q[0][2] = -((2.0 * p[0][2] / (width - 1)) - 1.0);\r
+ q[0][3] = 0.0;\r
+\r
+ q[1][0] = 0.0;\r
+ q[1][1] = -(2.0 * p[1][1] / (height - 1));\r
+ q[1][2] = -((2.0 * p[1][2] / (height - 1)) - 1.0);\r
+ q[1][3] = 0.0;\r
+\r
+ q[2][0] = 0.0;\r
+ q[2][1] = 0.0;\r
+ q[2][2] = (view_distance_max + view_distance_min) / (view_distance_min - view_distance_max);\r
+ q[2][3] = 2.0 * view_distance_max * view_distance_min / (view_distance_min - view_distance_max);\r
+\r
+ q[3][0] = 0.0;\r
+ q[3][1] = 0.0;\r
+ q[3][2] = -1.0;\r
+ q[3][3] = 0.0;\r
+\r
+ for (i = 0; i < 4; i++) { // Row.\r
+ // First 3 columns of the current row.\r
+ for (j = 0; j < 3; j++) { // Column.\r
+ o_gl_projection[i + j * 4] = q[i][0] * trans[0][j] + q[i][1] * trans[1][j] + q[i][2] * trans[2][j];\r
+ }\r
+ // Fourth column of the current row.\r
+ o_gl_projection[i + 3 * 4] = q[i][0] * trans[0][3] + q[i][1] * trans[1][3] + q[i][2] * trans[2][3] + q[i][3];\r
+ }\r
+ return;\r
+ }\r
+ \r
+ \r
+ \r
+ /**\r
+ * NyARTransMatResultをOpenGLの行列へ変換します。\r
+ * @param i_ny_result\r
+ * @param o_gl_result\r
+ * @throws NyARException\r
+ */\r
+ public void toCameraViewRH(NyARTransMatResult i_ny_result, double[] o_gl_result) throws NyARException\r
+ {\r
+ o_gl_result[0 + 0 * 4] = i_ny_result.m00; \r
+ o_gl_result[0 + 1 * 4] = i_ny_result.m01;\r
+ o_gl_result[0 + 2 * 4] = i_ny_result.m02;\r
+ o_gl_result[0 + 3 * 4] = i_ny_result.m03;\r
+ o_gl_result[1 + 0 * 4] = -i_ny_result.m10;\r
+ o_gl_result[1 + 1 * 4] = -i_ny_result.m11;\r
+ o_gl_result[1 + 2 * 4] = -i_ny_result.m12;\r
+ o_gl_result[1 + 3 * 4] = -i_ny_result.m13;\r
+ o_gl_result[2 + 0 * 4] = -i_ny_result.m20;\r
+ o_gl_result[2 + 1 * 4] = -i_ny_result.m21;\r
+ o_gl_result[2 + 2 * 4] = -i_ny_result.m22;\r
+ o_gl_result[2 + 3 * 4] = -i_ny_result.m23;\r
+ o_gl_result[3 + 0 * 4] = 0.0;\r
+ o_gl_result[3 + 1 * 4] = 0.0;\r
+ o_gl_result[3 + 2 * 4] = 0.0;\r
+ o_gl_result[3 + 3 * 4] = 1.0;\r
+ if (view_scale_factor != 0.0) {\r
+ o_gl_result[12] *= view_scale_factor;\r
+ o_gl_result[13] *= view_scale_factor;\r
+ o_gl_result[14] *= view_scale_factor;\r
+ }\r
+ return;\r
+ } \r
+ \r
+}\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry path="" kind="src"/>\r
+ <classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>\r
+ <classpathentry path="/NyARToolKit" combineaccessrules="false" kind="src"/>\r
+ <classpathentry path="C:/Program Files/QuickTime/QTSystem/QTJava.zip" kind="lib"/>\r
+ <classpathentry path="C:/Program Files/JMF2.1.1e/lib/jmf.jar" kind="lib"/>\r
+ <classpathentry path="" kind="output"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolkit.utils.qt</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit Quicktime utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * Copyright (C)2008 arc@dmz\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * \r
+ * <arc(at)digitalmuseum.jp>\r
+ * \r
+ */\r
+\r
+package jp.nyatla.nyartoolkit.qt.utils;\r
+\r
+import java.awt.Dimension;\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.ActionListener;\r
+import java.io.File;\r
+\r
+import javax.swing.Timer;\r
+\r
+import quicktime.QTException;\r
+import quicktime.QTSession;\r
+import quicktime.io.QTFile;\r
+import quicktime.qd.PixMap;\r
+import quicktime.qd.QDConstants;\r
+import quicktime.qd.QDGraphics;\r
+import quicktime.qd.QDRect;\r
+import quicktime.std.StdQTConstants;\r
+import quicktime.std.movies.Movie;\r
+import quicktime.std.movies.media.DataRef;\r
+import quicktime.std.sg.SGVideoChannel;\r
+import quicktime.std.sg.SequenceGrabber;\r
+import quicktime.util.RawEncodedImage;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * QuickTimeキャプチャクラス\r
+ *\r
+ */\r
+public class QtCameraCapture implements ActionListener\r
+{\r
+\r
+ private Dimension image_size;\r
+\r
+ private QtCaptureListener capture_listener;\r
+\r
+ protected float fps = 30; // キャプチャ画像を取得するfps\r
+\r
+ protected byte[] pixels; // キャプチャ画像の実データを保持するバイト型配列\r
+\r
+ // キャプチャに使うタイマー\r
+ private Timer timer;\r
+\r
+ // QTJava用のあれこれ\r
+ private QDGraphics graphics;\r
+\r
+ private QDRect bounds;\r
+\r
+ private SequenceGrabber grabber;\r
+\r
+ private SGVideoChannel channel;\r
+\r
+ private RawEncodedImage rawEncodedImage;\r
+\r
+ private Movie movie;\r
+\r
+ // ピクセルフォーマット変換用の一時変数\r
+ private int[] pixels_int;\r
+\r
+ public static final int PIXEL_FORMAT_RGB = quicktime.util.EndianOrder.isNativeLittleEndian() ? QDConstants.k32BGRAPixelFormat : QDGraphics.kDefaultPixelFormat;\r
+\r
+ public QtCameraCapture(int i_width, int i_height, float i_rate)\r
+ {\r
+ image_size = new Dimension(i_width, i_height);\r
+ fps = i_rate;\r
+ }\r
+\r
+ public Dimension getSize()\r
+ {\r
+ return image_size;\r
+ }\r
+\r
+ public byte[] readBuffer() throws NyARException\r
+ {\r
+ if (grabber == null) {\r
+ throw new NyARException();\r
+ }\r
+ return pixels;\r
+ }\r
+\r
+ public void setCaptureListener(QtCaptureListener i_listener) throws NyARException\r
+ {\r
+ if (grabber != null) {\r
+ throw new NyARException();\r
+ }\r
+ capture_listener = i_listener;\r
+\r
+ }\r
+\r
+ public void prepSetInput(Object input) throws QTException\r
+ {\r
+ QTSession.open();\r
+ bounds = new QDRect(image_size.width, image_size.height);\r
+ graphics = new QDGraphics(quicktime.util.EndianOrder.isNativeLittleEndian() ? QDConstants.k32BGRAPixelFormat : QDGraphics.kDefaultPixelFormat, bounds);\r
+ if (input != null && input.getClass().equals(File.class)) {\r
+ movie = quicktime.std.movies.Movie.fromDataRef(new DataRef(new QTFile((File) input)), StdQTConstants.newMovieActive);\r
+ } else {\r
+ grabber = new SequenceGrabber();\r
+ grabber.setGWorld(graphics, null);\r
+ channel = new SGVideoChannel(grabber);\r
+ channel.setBounds(bounds);\r
+\r
+ // seqGrabPreview == 2, Processingでmagic numberとしてハードコートされていた…\r
+ channel.setUsage(StdQTConstants.seqGrabPreview);\r
+\r
+ if (input != null) {\r
+ try {\r
+ channel.setDevice(input.toString());\r
+ } catch (QTException e) {\r
+ e.printStackTrace();\r
+ throw e;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Webcamの設定ダイアログを表示する。\r
+ * 既定のWebcamでは駄目な場合(複数のWebcamが接続されているPCなど)ではこれを実行するとよい。\r
+ */\r
+ public void prepShowDialog() throws QTException\r
+ {\r
+ channel.settingsDialog();\r
+ }\r
+\r
+ public void start() throws NyARException\r
+ {\r
+ try {\r
+\r
+ if (grabber == null)\r
+ prepSetInput(null);\r
+\r
+ if (movie == null) {\r
+ grabber.prepare(true, false); // あってもなくてもよさそう\r
+ grabber.startPreview();\r
+ } else {\r
+ movie.preroll(0, 1.0f);\r
+ while (movie.maxLoadedTimeInMovie() == 0)\r
+ movie.task(100);\r
+ movie.setRate(1);\r
+ movie.getPict(movie.getTime()).draw(graphics, bounds);\r
+ }\r
+ PixMap pixmap = graphics.getPixMap();\r
+ rawEncodedImage = pixmap.getPixelData();\r
+\r
+ image_size.width = rawEncodedImage.getRowBytes() / 4;\r
+ pixels = new byte[image_size.width * image_size.height * 3];\r
+ pixels_int = new int[image_size.width * image_size.height];\r
+ } catch (QTException e) {\r
+ QTSession.close();\r
+ throw new NyARException(e);\r
+ }\r
+\r
+ // キャプチャイメージを定期的に更新するタイマー\r
+ timer = new Timer((int) (1000 / fps), this);\r
+ timer.start();\r
+ }\r
+\r
+ public void stop()\r
+ {\r
+ finalize();\r
+ }\r
+\r
+ /** タイマー処理。キャプチャイメージの更新結果をリスナに伝える。 */\r
+ public void actionPerformed(ActionEvent event)\r
+ {\r
+\r
+ // 画像をQTJavaのRawEncodedImageとして取得\r
+ try {\r
+ if (movie == null) {\r
+ grabber.idle();\r
+ } else {\r
+ if (movie.isDone())\r
+ movie.goToBeginning();\r
+ movie.getPict(movie.getTime()).draw(graphics, bounds);\r
+ }\r
+ } catch (QTException e) {\r
+ QTSession.close();\r
+ e.printStackTrace();\r
+ }\r
+\r
+ // RawEncodedImageをint列に落とし込む\r
+ rawEncodedImage.copyToArray(0, pixels_int, 0, pixels_int.length);\r
+\r
+ // バイト列を生成する\r
+ int idx_byte = 0;\r
+ for (int idx = 0; idx < image_size.width * image_size.height; idx++) {\r
+ pixels[idx_byte++] = (byte) (pixels_int[idx] >> 16);\r
+ pixels[idx_byte++] = (byte) (pixels_int[idx] >> 8 & 0xff);\r
+ pixels[idx_byte++] = (byte) (pixels_int[idx] & 0xff);\r
+ }\r
+\r
+ // 各リスナに更新されたバイト列を渡す\r
+ capture_listener.onUpdateBuffer(pixels);\r
+ }\r
+\r
+ protected void finalize()\r
+ {\r
+ try {\r
+ if (movie == null) {\r
+ grabber.stop();\r
+ grabber.release();\r
+ grabber.disposeChannel(channel);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ } finally {\r
+ QTSession.close();\r
+ }\r
+ timer.stop();\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit Quicktime utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * Copyright (C)2008 arc@dmz\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * \r
+ * <arc(at)digitalmuseum.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.qt.utils;\r
+\r
+/**\r
+ * QuickTime リスナクラス\r
+ *\r
+ */\r
+public interface QtCaptureListener\r
+{\r
+ public void onUpdateBuffer(byte[] i_buffer);\r
+ \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit Quicktime utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * Copyright (C)2008 arc@dmz\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * \r
+ * <arc(at)digitalmuseum.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.qt.utils;\r
+\r
+import java.awt.image.BufferedImage;\r
+import java.awt.image.DataBuffer;\r
+import java.awt.image.WritableRaster;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster_BasicClass;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * RGB形式のbyte配列をラップするNyARRasterです。\r
+ * 保持したデータからBufferedImageを出力する機能も持ちます。\r
+ */\r
+public class QtNyARRaster_RGB extends NyARRgbRaster_BasicClass\r
+{\r
+ private class PixcelReader extends NyARRgbPixelReader_RGB24 implements INyARBufferReader\r
+ {\r
+ public PixcelReader(NyARIntSize i_size)\r
+ {\r
+ super(null, i_size);\r
+ return;\r
+ }\r
+\r
+ public void syncBuffer(byte[] i_ref_buffer)\r
+ {\r
+ this._ref_buf = i_ref_buffer;\r
+ return;\r
+ }\r
+\r
+ //\r
+ // INyARBufferReader\r
+ //\r
+ public Object getBuffer()\r
+ {\r
+ return this._ref_buf;\r
+ }\r
+\r
+ public int getBufferType()\r
+ {\r
+ return INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24;\r
+ }\r
+\r
+ public boolean isEqualBufferType(int i_type_value)\r
+ {\r
+ return i_type_value == INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24;\r
+ }\r
+ }\r
+\r
+ protected byte[] _ref_buf;\r
+\r
+ protected PixcelReader _reader;\r
+\r
+ private WritableRaster _raster;\r
+\r
+ private BufferedImage _image;\r
+\r
+ /**\r
+ * RGB形式のJMFバッファをラップするオブジェクトをつくります。 生成直後のオブジェクトはデータを持ちません。 メンバ関数はsetBufferを実行後に使用可能になります。\r
+ */\r
+ public QtNyARRaster_RGB(int i_width, int i_height)\r
+ {\r
+ super(new NyARIntSize(i_width,i_height));\r
+ this._ref_buf = null;\r
+ this._reader = new PixcelReader(this._size);\r
+ _raster = WritableRaster.createInterleavedRaster(DataBuffer.TYPE_BYTE, i_width, i_height, i_width * 3, 3, new int[] { 0, 1, 2 }, null);\r
+ _image = new BufferedImage(i_width, i_height, BufferedImage.TYPE_3BYTE_BGR);\r
+ }\r
+\r
+ /**\r
+ * javax.media.Bufferを分析して、その分析結果をNyARRasterに適合する形で保持します。 関数実行後に外部でi_bufferの内容変更した場合には、再度setBuffer関数を呼び出してください。\r
+ * \r
+ * @param i_buffer\r
+ * RGB形式のデータを格納したjavax.media.Bufferオブジェクトを指定してください。\r
+ * @return i_bufferをラップしたオブジェクトを返します。\r
+ * @throws NyARException\r
+ */\r
+ public void setBuffer(byte[] i_buffer)\r
+ {\r
+ this._ref_buf = i_buffer;\r
+ this._reader.syncBuffer(i_buffer);\r
+ }\r
+\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._reader;\r
+ }\r
+\r
+ public INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._reader;\r
+ }\r
+\r
+ /**\r
+ * データを持っているかを返します。\r
+ * \r
+ * @return\r
+ */\r
+ public boolean hasData()\r
+ {\r
+ return this._ref_buf != null;\r
+ }\r
+\r
+ /**\r
+ * 保持しているデータからBufferedImageを作って返します。\r
+ * \r
+ * @return\r
+ */\r
+ public BufferedImage createImage()\r
+ {\r
+ _raster.setDataElements(0, 0, this._size.w, this._size.h, this._ref_buf);\r
+ _image.setData(_raster);\r
+ return _image;\r
+ }\r
+\r
+}\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry kind="src" path=""/>\r
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>\r
+ <classpathentry kind="output" path=""/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>NyARToolKit</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit;\r
+\r
+/**\r
+ * NyARToolkitライブラリが生成するExceptionオブジェクトです。\r
+ *\r
+ */\r
+public class NyARException extends Exception\r
+{\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public NyARException()\r
+ {\r
+ super();\r
+ }\r
+\r
+ public NyARException(Exception e)\r
+ {\r
+ super(e);\r
+ }\r
+\r
+ public NyARException(String m)\r
+ {\r
+ super(m);\r
+ }\r
+\r
+ public static void trap(String m) throws NyARException\r
+ {\r
+ throw new NyARException("トラップ:" + m);\r
+ }\r
+\r
+ public static void notImplement() throws NyARException\r
+ {\r
+ throw new NyARException("Not Implement!");\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import java.io.FileInputStream;\r
+import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
+import java.io.StreamTokenizer;\r
+\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+class NyARCodeFileReader\r
+{\r
+\r
+ /**\r
+ * ARコードファイルからデータを読み込んでo_raster[4]に格納します。\r
+ * @param i_stream\r
+ * @param o_raster\r
+ * @throws NyARException\r
+ */\r
+ public static void loadFromARToolKitFormFile(InputStream i_stream,NyARRaster[] o_raster) throws NyARException\r
+ {\r
+ assert o_raster.length==4;\r
+ //4個の要素をラスタにセットする。\r
+ try {\r
+ StreamTokenizer st = new StreamTokenizer(new InputStreamReader(i_stream));\r
+ //GBRAで一度読みだす。\r
+ for (int h = 0; h < 4; h++) {\r
+ assert o_raster[h].getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ final NyARRaster ra=o_raster[h];\r
+ readBlock(st,ra.getWidth(),ra.getHeight(),(int[])ra.getBufferReader().getBuffer());\r
+ }\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * ARコードファイルからデータを読み込んでo_codeに格納します。\r
+ * @param i_stream\r
+ * @param o_code\r
+ * @throws NyARException\r
+ */\r
+ public static void loadFromARToolKitFormFile(InputStream i_stream,NyARCode o_code) throws NyARException\r
+ {\r
+ int width=o_code.getWidth();\r
+ int height=o_code.getHeight();\r
+ NyARRaster tmp_raster=new NyARRaster(new NyARIntSize(width,height),new int[width*height],INyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ //4個の要素をラスタにセットする。\r
+ try {\r
+ StreamTokenizer st = new StreamTokenizer(new InputStreamReader(i_stream));\r
+ int[] buf=(int[])tmp_raster.getBufferReader().getBuffer();\r
+ //GBRAで一度読みだす。\r
+ for (int h = 0; h < 4; h++){\r
+ readBlock(st,width,height,buf);\r
+ //ARCodeにセット(カラー)\r
+ o_code.getColorData(h).setRaster(tmp_raster);\r
+ o_code.getBlackWhiteData(h).setRaster(tmp_raster);\r
+ }\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ tmp_raster=null;//ポイ\r
+ return;\r
+ }\r
+ /**\r
+ * 1ブロック分のXRGBデータをi_stからo_bufへ読みだします。\r
+ * @param i_st\r
+ * @param o_buf\r
+ */\r
+ private static void readBlock(StreamTokenizer i_st,int i_width,int i_height,int[] o_buf) throws NyARException\r
+ {\r
+ try {\r
+ final int pixels=i_width*i_height;\r
+ for (int i3 = 0; i3 < 3; i3++) {\r
+ for (int i2 = 0; i2 < pixels; i2++){\r
+ // 数値のみ読み出す\r
+ switch (i_st.nextToken()){\r
+ case StreamTokenizer.TT_NUMBER:\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ o_buf[i2]=(o_buf[i2]<<8)|((0x000000ff&(int)i_st.nval));\r
+ }\r
+ }\r
+ //GBR→RGB\r
+ for(int i3=0;i3<pixels;i3++){\r
+ o_buf[i3]=((o_buf[i3]<<16)&0xff0000)|(o_buf[i3]&0x00ff00)|((o_buf[i3]>>16)&0x0000ff);\r
+ }\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ } \r
+ return;\r
+ }\r
+}\r
+\r
+/**\r
+ * ARToolKitのマーカーコードを1個保持します。\r
+ * \r
+ */\r
+public class NyARCode\r
+{\r
+ private NyARMatchPattDeviationColorData[] _color_pat=new NyARMatchPattDeviationColorData[4];\r
+ private NyARMatchPattDeviationBlackWhiteData[] _bw_pat=new NyARMatchPattDeviationBlackWhiteData[4];\r
+ private int _width;\r
+ private int _height;\r
+ \r
+ public NyARMatchPattDeviationColorData getColorData(int i_index)\r
+ {\r
+ return this._color_pat[i_index];\r
+ }\r
+ public NyARMatchPattDeviationBlackWhiteData getBlackWhiteData(int i_index)\r
+ {\r
+ return this._bw_pat[i_index];\r
+ } \r
+ public int getWidth()\r
+ {\r
+ return _width;\r
+ }\r
+\r
+ public int getHeight()\r
+ {\r
+ return _height;\r
+ }\r
+ public NyARCode(int i_width, int i_height) throws NyARException\r
+ {\r
+ this._width = i_width;\r
+ this._height = i_height;\r
+ //空のラスタを4個作成\r
+ for(int i=0;i<4;i++){\r
+ this._color_pat[i]=new NyARMatchPattDeviationColorData(i_width,i_height);\r
+ this._bw_pat[i]=new NyARMatchPattDeviationBlackWhiteData(i_width,i_height);\r
+ }\r
+ return;\r
+ }\r
+ public void loadARPattFromFile(String filename) throws NyARException\r
+ {\r
+ try {\r
+ loadARPatt(new FileInputStream(filename));\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ return;\r
+ }\r
+ public void setRaster(NyARRaster[] i_raster) throws NyARException\r
+ {\r
+ assert i_raster.length!=4;\r
+ //ラスタにパターンをロードする。\r
+ for(int i=0;i<4;i++){\r
+ this._color_pat[i].setRaster(i_raster[i]); \r
+ }\r
+ return;\r
+ }\r
+\r
+ public void loadARPatt(InputStream i_stream) throws NyARException\r
+ {\r
+ //ラスタにパターンをロードする。\r
+ NyARCodeFileReader.loadFromARToolKitFormFile(i_stream,this);\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+/**\r
+ * ARMat構造体に対応するクラス typedef struct { double *m; int row; int clm; }ARMat;\r
+ * \r
+ */\r
+public class NyARMat\r
+{\r
+ /**\r
+ * 配列サイズと行列サイズは必ずしも一致しないことに注意 返された配列のサイズを行列の大きさとして使わないこと!\r
+ * \r
+ */\r
+ protected double[][] _m;\r
+ private int[] __matrixSelfInv_nos;\r
+\r
+ protected int clm;\r
+ protected int row;\r
+\r
+ /**\r
+ * デフォルトコンストラクタは機能しません。\r
+ * \r
+ * @throws NyARException\r
+ */\r
+ protected NyARMat() throws NyARException\r
+ {\r
+ throw new NyARException();\r
+ }\r
+\r
+ public NyARMat(int i_row, int i_clm)\r
+ {\r
+ this._m = new double[i_row][i_clm];\r
+ this.clm = i_clm;\r
+ this.row = i_row;\r
+ this.__matrixSelfInv_nos=new int[i_row];\r
+ return;\r
+ }\r
+ \r
+ /**\r
+ * 行列の列数を返します。\r
+ * @return\r
+ */\r
+ public int getClm()\r
+ {\r
+ return clm;\r
+ }\r
+ /**\r
+ * 行列の行数を返します。\r
+ * @return\r
+ */\r
+ public int getRow()\r
+ {\r
+ return row;\r
+ } \r
+ \r
+ /**\r
+ * 行列のサイズを変更します。\r
+ * 実行後、行列の各値は不定になります。\r
+ * @param i_row\r
+ * @param i_clm\r
+ */\r
+ public void realloc(int i_row, int i_clm)\r
+ {\r
+ if (i_row <= this._m.length && i_clm <= this._m[0].length) {\r
+ // 十分な配列があれば何もしない。\r
+ } else {\r
+ // 不十分なら取り直す。\r
+ this._m = new double[i_row][i_clm];\r
+ this.__matrixSelfInv_nos=new int[i_row];\r
+ }\r
+ this.clm = i_clm;\r
+ this.row = i_row;\r
+ return;\r
+ }\r
+ \r
+ \r
+ \r
+ /**\r
+ * i_mat_aとi_mat_bの積を計算して、thisへ格納します。\r
+ * @param i_mat_a\r
+ * @param i_mat_b\r
+ * @throws NyARException\r
+ */\r
+ public void matrixMul(NyARMat i_mat_a, NyARMat i_mat_b) throws NyARException\r
+ {\r
+ assert i_mat_a.clm == i_mat_b.row && this.row==i_mat_a.row && this.clm==i_mat_b.clm;\r
+\r
+ double w;\r
+ int r, c, i;\r
+ double[][] am = i_mat_a._m, bm = i_mat_b._m, dm = this._m;\r
+ // For順変更禁止\r
+ for (r = 0; r < this.row; r++) {\r
+ for (c = 0; c < this.clm; c++) {\r
+ w = 0.0;\r
+ for (i = 0; i < i_mat_a.clm; i++) {\r
+ w += am[r][i] * bm[i][c];\r
+ }\r
+ dm[r][c] = w;\r
+ }\r
+ }\r
+ return;\r
+ } \r
+ \r
+ /**\r
+ * 逆行列を計算して、thisへ格納します。\r
+ * @throws NyARException\r
+ */\r
+ public boolean matrixSelfInv() throws NyARException\r
+ {\r
+ double[][] ap = this._m;\r
+ int dimen = this.row;\r
+ int dimen_1 = dimen - 1;\r
+ double[] ap_n, ap_ip, ap_i;// wap;\r
+ int j, ip, nwork;\r
+ int[] nos = __matrixSelfInv_nos;//ワーク変数\r
+ // double epsl;\r
+ double p, pbuf, work;\r
+\r
+ /* check size */\r
+ switch (dimen) {\r
+ case 0:\r
+ throw new NyARException();\r
+ case 1:\r
+ ap[0][0] = 1.0 / ap[0][0];// *ap = 1.0 / (*ap);\r
+ return true;/* 1 dimension */\r
+ }\r
+\r
+ for (int n = 0; n < dimen; n++) {\r
+ nos[n] = n;\r
+ }\r
+\r
+ /*\r
+ * nyatla memo ipが定まらないで計算が行われる場合があるので挿入。 ループ内で0初期化していいかが判らない。\r
+ */\r
+ ip = 0;\r
+ // For順変更禁止\r
+ for (int n = 0; n < dimen; n++) {\r
+ ap_n = ap[n];// wcp = ap + n * rowa;\r
+ p = 0.0;\r
+ for (int i = n; i < dimen; i++) {\r
+ if (p < (pbuf = Math.abs(ap[i][0]))) {\r
+ p = pbuf;\r
+ ip = i;\r
+ }\r
+ }\r
+ // if (p <= matrixSelfInv_epsl){\r
+ if (p == 0.0) {\r
+ return false;\r
+ // throw new NyARException();\r
+ }\r
+\r
+ nwork = nos[ip];\r
+ nos[ip] = nos[n];\r
+ nos[n] = nwork;\r
+\r
+ ap_ip = ap[ip];\r
+ for (j = 0; j < dimen; j++) {// for(j = 0, wap = ap + ip * rowa,\r
+ // wbp = wcp; j < dimen ; j++) {\r
+ work = ap_ip[j]; // work = *wap;\r
+ ap_ip[j] = ap_n[j];\r
+ ap_n[j] = work;\r
+ }\r
+\r
+ work = ap_n[0];\r
+ for (j = 0; j < dimen_1; j++) {\r
+ ap_n[j] = ap_n[j + 1] / work;// *wap = *(wap + 1) / work;\r
+ }\r
+ ap_n[j] = 1.0 / work;// *wap = 1.0 / work;\r
+ for (int i = 0; i < dimen; i++) {\r
+ if (i != n) {\r
+ ap_i = ap[i];// wap = ap + i * rowa;\r
+ work = ap_i[0];\r
+ for (j = 0; j < dimen_1; j++) {// for(j = 1, wbp = wcp,work = *wap;j < dimen ;j++, wap++, wbp++)\r
+ ap_i[j] = ap_i[j + 1] - work * ap_n[j];// wap = *(wap +1) - work *(*wbp);\r
+ }\r
+ ap_i[j] = -work * ap_n[j];// *wap = -work * (*wbp);\r
+ }\r
+ }\r
+ }\r
+\r
+ for (int n = 0; n < dimen; n++) {\r
+ for (j = n; j < dimen; j++) {\r
+ if (nos[j] == n) {\r
+ break;\r
+ }\r
+ }\r
+ nos[j] = nos[n];\r
+ for (int i = 0; i < dimen; i++) {\r
+ ap_i = ap[i];\r
+ work = ap_i[j];// work = *wap;\r
+ ap_i[j] = ap_i[n];// *wap = *wbp;\r
+ ap_i[n] = work;// *wbp = work;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * 行列をゼロクリアする。\r
+ */\r
+ public void zeroClear()\r
+ {\r
+ int i, i2;\r
+ // For順変更OK\r
+ for (i = row - 1; i >= 0; i--) {\r
+ for (i2 = clm - 1; i2 >= 0; i2--) {\r
+ _m[i][i2] = 0.0;\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * i_copy_fromの内容を自分自身にコピーします。 高さ・幅は同一で無いと失敗します。\r
+ * \r
+ * @param i_copy_from\r
+ */\r
+ public void copyFrom(NyARMat i_copy_from) throws NyARException\r
+ {\r
+ // サイズ確認\r
+ if (this.row != i_copy_from.row || this.clm != i_copy_from.clm) {\r
+ throw new NyARException();\r
+ }\r
+ // 値コピー\r
+ for (int r = this.row - 1; r >= 0; r--) {\r
+ for (int c = this.clm - 1; c >= 0; c--) {\r
+ this._m[r][c] = i_copy_from._m[r][c];\r
+ }\r
+ }\r
+ }\r
+\r
+ public double[][] getArray()\r
+ {\r
+ return _m;\r
+ }\r
+\r
+\r
+ /**\r
+ * sourceの転置行列をdestに得る。arMatrixTrans()の代替品\r
+ * \r
+ * @param dest\r
+ * @param source\r
+ * @return\r
+ */\r
+ public static void matrixTrans(NyARMat dest, NyARMat source) throws NyARException\r
+ {\r
+ if (dest.row != source.clm || dest.clm != source.row) {\r
+ throw new NyARException();\r
+ }\r
+ NyARException.trap("未チェックのパス");\r
+ // For順変更禁止\r
+ for (int r = 0; r < dest.row; r++) {\r
+ for (int c = 0; c < dest.clm; c++) {\r
+ dest._m[r][c] = source._m[c][r];\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * unitを単位行列に初期化する。arMatrixUnitの代替品\r
+ * \r
+ * @param unit\r
+ */\r
+ public static void matrixUnit(NyARMat unit) throws NyARException\r
+ {\r
+ if (unit.row != unit.clm) {\r
+ throw new NyARException();\r
+ }\r
+ NyARException.trap("未チェックのパス");\r
+ // For順変更禁止\r
+ for (int r = 0; r < unit.getRow(); r++) {\r
+ for (int c = 0; c < unit.getClm(); c++) {\r
+ if (r == c) {\r
+ unit._m[r][c] = 1.0;\r
+ } else {\r
+ unit._m[r][c] = 0.0;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * sourceの内容を自身に複製する。 Optimized 2008.04.19\r
+ * \r
+ * @param i_source\r
+ * @return\r
+ */\r
+ public void matrixDup(NyARMat i_source) throws NyARException\r
+ {\r
+ // 自身の配列サイズを相手のそれより大きいことを保障する。\r
+ this.realloc(i_source.row, i_source.clm);\r
+ // 内容を転写\r
+ int r, c;\r
+ double[][] src_m, dest_m;\r
+ src_m = i_source._m;\r
+ dest_m = this._m;\r
+ // コピーはFor順を変えてもOK\r
+ for (r = this.row - 1; r >= 0; r--) {\r
+ for (c = this.clm - 1; c >= 0; c--) {\r
+ dest_m[r][c] = src_m[r][c];\r
+ }\r
+ }\r
+ }\r
+\r
+ public NyARMat matrixAllocDup() throws NyARException\r
+ {\r
+ NyARMat result = new NyARMat(this.row, this.clm);\r
+ // コピー\r
+ int r, c;\r
+ double[][] dest_m, src_m;\r
+ dest_m = result._m;\r
+ src_m = this._m;\r
+ // コピーはFor順を変えてもOK\r
+ for (r = this.row - 1; r >= 0; r--) {\r
+ for (c = this.clm - 1; c >= 0; c--) {\r
+ dest_m[r][c] = src_m[r][c];\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+\r
+\r
+ private static final double PCA_EPS = 1e-6; // #define EPS 1e-6\r
+\r
+ private static final int PCA_MAX_ITER = 100; // #define MAX_ITER 100\r
+\r
+ private static final double PCA_VZERO = 1e-16; // #define VZERO 1e-16\r
+\r
+ /**\r
+ * static int EX( ARMat *input, ARVec *mean )の代替関数 Optimize:STEP:[144->110]\r
+ * \r
+ * @param input\r
+ * @param mean\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ private void PCA_EX(NyARVec mean) throws NyARException\r
+ {\r
+ int lrow, lclm;\r
+ int i, i2;\r
+ lrow = this.row;\r
+ lclm = this.clm;\r
+ double[][] lm = this._m;\r
+\r
+ if (lrow <= 0 || lclm <= 0) {\r
+ throw new NyARException();\r
+ }\r
+ if (mean.getClm() != lclm) {\r
+ throw new NyARException();\r
+ }\r
+ // double[] mean_array=mean.getArray();\r
+ // mean.zeroClear();\r
+ final double[] mean_array = mean.getArray();\r
+ double w;\r
+ // For順変更禁止\r
+ for (i2 = 0; i2 < lclm; i2++) {\r
+ w = 0.0;\r
+ for (i = 0; i < lrow; i++) {\r
+ // *(v++) += *(m++);\r
+ w += lm[i][i2];\r
+ }\r
+ mean_array[i2] = w / lrow;// mean->v[i] /= row;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * static int CENTER( ARMat *inout, ARVec *mean )の代替関数\r
+ * \r
+ * @param inout\r
+ * @param mean\r
+ * @return\r
+ */\r
+ private static void PCA_CENTER(NyARMat inout, NyARVec mean)throws NyARException\r
+ {\r
+ double[] v;\r
+ int row, clm;\r
+\r
+ row = inout.row;\r
+ clm = inout.clm;\r
+ if (mean.getClm() != clm) {\r
+ throw new NyARException();\r
+ }\r
+ double[][] im = inout._m;\r
+ double[] im_i;\r
+ double w0, w1;\r
+ v = mean.getArray();\r
+ // 特にパフォーマンスが劣化するclm=1と2ときだけ、別パスで処理します。\r
+ switch (clm) {\r
+ case 1:\r
+ w0 = v[0];\r
+ for (int i = 0; i < row; i++) {\r
+ im[i][0] -= w0;\r
+ }\r
+ break;\r
+ case 2:\r
+ w0 = v[0];\r
+ w1 = v[1];\r
+ for (int i = 0; i < row; i++) {\r
+ im_i = im[i];\r
+ im_i[0] -= w0;\r
+ im_i[1] -= w1;\r
+ }\r
+ break;\r
+ default:\r
+ for (int i = 0; i < row; i++) {\r
+ im_i = im[i];\r
+ for (int j = 0; j < clm; j++) {\r
+ // *(m++) -= *(v++);\r
+ im_i[j] -= v[j];\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * int x_by_xt( ARMat *input, ARMat *output )の代替関数\r
+ * \r
+ * @param input\r
+ * @param output\r
+ * @throws NyARException\r
+ */\r
+ private static void PCA_x_by_xt(NyARMat input, NyARMat output) throws NyARException\r
+ {\r
+ NyARException.trap("動作未チェック/配列化未チェック");\r
+ int row, clm;\r
+ // double[][] out;\r
+ double[] in1, in2;\r
+\r
+ NyARException.trap("未チェックのパス");\r
+ row = input.row;\r
+ clm = input.clm;\r
+ NyARException.trap("未チェックのパス");\r
+ if (output.row != row || output.clm != row) {\r
+ throw new NyARException();\r
+ }\r
+\r
+ // out = output.getArray();\r
+ for (int i = 0; i < row; i++) {\r
+ for (int j = 0; j < row; j++) {\r
+ if (j < i) {\r
+ NyARException.trap("未チェックのパス");\r
+ output._m[i][j] = output._m[j][i];// *out =\r
+ // output->m[j*row+i];\r
+ } else {\r
+ NyARException.trap("未チェックのパス");\r
+ in1 = input._m[i];// input.getRowArray(i);//in1 = &(input->m[clm*i]);\r
+ in2 = input._m[j];// input.getRowArray(j);//in2 = &(input->m[clm*j]);\r
+ output._m[i][j] = 0;// *out = 0.0;\r
+ for (int k = 0; k < clm; k++) {\r
+ output._m[i][j] += (in1[k] * in2[k]);// *out += *(in1++)\r
+ // * *(in2++);\r
+ }\r
+ }\r
+ // out.incPtr();\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * static int xt_by_x( ARMat *input, ARMat *output )の代替関数\r
+ * Optimize:2008.04.19\r
+ * \r
+ * @param input\r
+ * @param i_output\r
+ * @throws NyARException\r
+ */\r
+ private static void PCA_xt_by_x(NyARMat input, NyARMat i_output) throws NyARException\r
+ {\r
+ double[] in_;\r
+ int row, clm;\r
+\r
+ row = input.row;\r
+ clm = input.clm;\r
+ if (i_output.row != clm || i_output.clm != clm) {\r
+ throw new NyARException();\r
+ }\r
+\r
+ int k, j;\r
+ double[][] out_m = i_output._m;\r
+ double w;\r
+ for (int i = 0; i < clm; i++) {\r
+ for (j = 0; j < clm; j++) {\r
+ if (j < i) {\r
+ out_m[i][j] = out_m[j][i];// *out = output->m[j*clm+i];\r
+ } else {\r
+ w = 0.0;// *out = 0.0;\r
+ for (k = 0; k < row; k++) {\r
+ in_ = input._m[k];// in=input.getRowArray(k);\r
+ w += (in_[i] * in_[j]);// *out += *in1 * *in2;\r
+ }\r
+ out_m[i][j] = w;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private final NyARVec wk_PCA_QRM_ev = new NyARVec(1);\r
+\r
+ /**\r
+ * static int QRM( ARMat *a, ARVec *dv )の代替関数\r
+ * \r
+ * @param a\r
+ * @param dv\r
+ * @throws NyARException\r
+ */\r
+ private void PCA_QRM(NyARVec dv) throws NyARException\r
+ {\r
+ double w, t, s, x, y, c;\r
+ int dim, iter;\r
+ double[] dv_array = dv.getArray();\r
+\r
+ dim = this.row;\r
+ if (dim != this.clm || dim < 2) {\r
+ throw new NyARException();\r
+ }\r
+ if (dv.getClm() != dim) {\r
+ throw new NyARException();\r
+ }\r
+\r
+ NyARVec ev = this.wk_PCA_QRM_ev;\r
+ ev.realloc(dim);\r
+ double[] ev_array = ev.getArray();\r
+ if (ev == null) {\r
+ throw new NyARException();\r
+ }\r
+ final double[][] L_m = this._m;\r
+ this.vecTridiagonalize(dv, ev, 1);\r
+\r
+ ev_array[0] = 0.0;// ev->v[0] = 0.0;\r
+ for (int h = dim - 1; h > 0; h--) {\r
+ int j = h;\r
+ while (j > 0&& Math.abs(ev_array[j]) > PCA_EPS* (Math.abs(dv_array[j - 1]) + Math.abs(dv_array[j]))) {// while(j>0 && fabs(ev->v[j]) >EPS*(fabs(dv->v[j-1])+fabs(dv->v[j])))\r
+ // j--;\r
+ j--;\r
+ }\r
+ if (j == h) {\r
+ continue;\r
+ }\r
+ iter = 0;\r
+ do {\r
+ iter++;\r
+ if (iter > PCA_MAX_ITER) {\r
+ break;\r
+ }\r
+ w = (dv_array[h - 1] - dv_array[h]) / 2;// w = (dv->v[h-1] -dv->v[h]) / 2;//ここ?\r
+ t = ev_array[h] * ev_array[h];// t = ev->v[h] * ev->v[h];\r
+ s = Math.sqrt(w * w + t);\r
+ if (w < 0) {\r
+ s = -s;\r
+ }\r
+ x = dv_array[j] - dv_array[h] + t / (w + s);// x = dv->v[j] -dv->v[h] +t/(w+s);\r
+ y = ev_array[j + 1];// y = ev->v[j+1];\r
+ for (int k = j; k < h; k++) {\r
+ if (Math.abs(x) >= Math.abs(y)) {\r
+ if (Math.abs(x) > PCA_VZERO) {\r
+ t = -y / x;\r
+ c = 1 / Math.sqrt(t * t + 1);\r
+ s = t * c;\r
+ } else {\r
+ c = 1.0;\r
+ s = 0.0;\r
+ }\r
+ } else {\r
+ t = -x / y;\r
+ s = 1.0 / Math.sqrt(t * t + 1);\r
+ c = t * s;\r
+ }\r
+ w = dv_array[k] - dv_array[k + 1];// w = dv->v[k] -dv->v[k+1];\r
+ t = (w * s + 2 * c * ev_array[k + 1]) * s;// t = (w * s +2 * c *ev->v[k+1]) *s;\r
+ dv_array[k] -= t;// dv->v[k] -= t;\r
+ dv_array[k + 1] += t;// dv->v[k+1] += t;\r
+ if (k > j) {\r
+ NyARException.trap("未チェックパス");\r
+ {\r
+ ev_array[k] = c * ev_array[k] - s * y;// ev->v[k]= c *ev->v[k]- s * y;\r
+ }\r
+ }\r
+ ev_array[k + 1] += s * (c * w - 2 * s * ev_array[k + 1]);// ev->v[k+1]+= s * (c* w- 2* s *ev->v[k+1]);\r
+\r
+ for (int i = 0; i < dim; i++) {\r
+ x = L_m[k][i];// x = a->m[k*dim+i];\r
+ y = L_m[k + 1][i];// y = a->m[(k+1)*dim+i];\r
+ L_m[k][i] = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;\r
+ L_m[k + 1][i] = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;\r
+ }\r
+ if (k < h - 1) {\r
+ NyARException.trap("未チェックパス");\r
+ {\r
+ x = ev_array[k + 1];// x = ev->v[k+1];\r
+ y = -s * ev_array[k + 2];// y = -s * ev->v[k+2];\r
+ ev_array[k + 2] *= c;// ev->v[k+2] *= c;\r
+ }\r
+ }\r
+ }\r
+ } while (Math.abs(ev_array[h]) > PCA_EPS\r
+ * (Math.abs(dv_array[h - 1]) + Math.abs(dv_array[h])));\r
+ }\r
+ for (int k = 0; k < dim - 1; k++) {\r
+ int h = k;\r
+ t = dv_array[h];// t = dv->v[h];\r
+ for (int i = k + 1; i < dim; i++) {\r
+ if (dv_array[i] > t) {// if( dv->v[i] > t ) {\r
+ h = i;\r
+ t = dv_array[h];// t = dv->v[h];\r
+ }\r
+ }\r
+ dv_array[h] = dv_array[k];// dv->v[h] = dv->v[k];\r
+ dv_array[k] = t;// dv->v[k] = t;\r
+ this.flipRow(h, k);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * i_row_1番目の行と、i_row_2番目の行を入れ替える。\r
+ * \r
+ * @param i_row_1\r
+ * @param i_row_2\r
+ */\r
+ private void flipRow(int i_row_1, int i_row_2)\r
+ {\r
+ int i;\r
+ double w;\r
+ double[] r1 = this._m[i_row_1], r2 = this._m[i_row_2];\r
+ // For順変更OK\r
+ for (i = clm - 1; i >= 0; i--) {\r
+ w = r1[i];\r
+ r1[i] = r2[i];\r
+ r2[i] = w;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * static int EV_create( ARMat *input, ARMat *u, ARMat *output, ARVec *ev\r
+ * )の代替関数\r
+ * \r
+ * @param input\r
+ * @param u\r
+ * @param output\r
+ * @param ev\r
+ * @throws NyARException\r
+ */\r
+ private static void PCA_EV_create(NyARMat input, NyARMat u, NyARMat output,NyARVec ev) throws NyARException\r
+ {\r
+ NyARException.trap("未チェックのパス");\r
+ int row, clm;\r
+ row = input.row;// row = input->row;\r
+ clm = input.clm;// clm = input->clm;\r
+ if (row <= 0 || clm <= 0) {\r
+ throw new NyARException();\r
+ }\r
+ if (u.row != row || u.clm != row) {// if( u->row != row || u->clm !=\r
+ // row ){\r
+ throw new NyARException();\r
+ }\r
+ if (output.row != row || output.clm != clm) {// if( output->row !=\r
+ // row || output->clm !=\r
+ // clm ){\r
+ throw new NyARException();\r
+ }\r
+ if (ev.getClm() != row) {// if( ev->clm != row ){\r
+ throw new NyARException();\r
+ }\r
+ double[][] m, in_;\r
+ double[] m1, ev_array;\r
+ double sum, work;\r
+\r
+ NyARException.trap("未チェックのパス");\r
+ m = output._m;// m = output->m;\r
+ in_ = input._m;\r
+ int i;\r
+ ev_array = ev.getArray();\r
+ for (i = 0; i < row; i++) {\r
+ NyARException.trap("未チェックのパス");\r
+ if (ev_array[i] < PCA_VZERO) {// if( ev->v[i] < VZERO ){\r
+ break;\r
+ }\r
+ NyARException.trap("未チェックのパス");\r
+ work = 1 / Math.sqrt(Math.abs(ev_array[i]));// work = 1 /\r
+ // sqrt(fabs(ev->v[i]));\r
+ for (int j = 0; j < clm; j++) {\r
+ sum = 0.0;\r
+ m1 = u._m[i];// m1 = &(u->m[i*row]);\r
+ // m2=input.getPointer(j);//m2 = &(input->m[j]);\r
+ for (int k = 0; k < row; k++) {\r
+ sum += m1[k] + in_[k][j];// sum += *m1 * *m2;\r
+ // m1.incPtr(); //m1++;\r
+ // m2.addPtr(clm);//m2 += clm;\r
+ }\r
+ m1[j] = sum * work;// *(m++) = sum * work;\r
+ // {//*(m++) = sum * work;\r
+ // m.set(sum * work);\r
+ // m.incPtr();}\r
+ }\r
+ }\r
+ for (; i < row; i++) {\r
+ NyARException.trap("未チェックのパス");\r
+ ev_array[i] = 0.0;// ev->v[i] = 0.0;\r
+ for (int j = 0; j < clm; j++) {\r
+ m[i][j] = 0.0;\r
+ // m.set(0.0);//*(m++) = 0.0;\r
+ // m.incPtr();\r
+ }\r
+ }\r
+ }\r
+\r
+ private NyARMat wk_PCA_PCA_u = null;\r
+\r
+ /**\r
+ * static int PCA( ARMat *input, ARMat *output, ARVec *ev )\r
+ * \r
+ * @param output\r
+ * @param o_ev\r
+ * @throws NyARException\r
+ */\r
+ private void PCA_PCA(NyARMat o_output, NyARVec o_ev) throws NyARException\r
+ {\r
+\r
+ int l_row, l_clm, min;\r
+ double[] ev_array = o_ev.getArray();\r
+\r
+ l_row = this.row;// row = input->row;\r
+ l_clm = this.clm;// clm = input->clm;\r
+ min = (l_clm < l_row) ? l_clm : l_row;\r
+ if (l_row < 2 || l_clm < 2) {\r
+ throw new NyARException();\r
+ }\r
+ if (o_output.clm != this.clm) {// if( output->clm != input->clm ){\r
+ throw new NyARException();\r
+ }\r
+ if (o_output.row != min) {// if( output->row != min ){\r
+ throw new NyARException();\r
+ }\r
+ if (o_ev.getClm() != min) {// if( ev->clm != min ){\r
+ throw new NyARException();\r
+ }\r
+\r
+ NyARMat u;// u =new NyARMat( min, min );\r
+ if (this.wk_PCA_PCA_u == null) {\r
+ u = new NyARMat(min, min);\r
+ this.wk_PCA_PCA_u = u;\r
+ } else {\r
+ u = this.wk_PCA_PCA_u;\r
+ u.realloc(min, min);\r
+ }\r
+\r
+ if (l_row < l_clm) {\r
+ NyARException.trap("未チェックのパス");\r
+ PCA_x_by_xt(this, u);// if(x_by_xt( input, u ) < 0 ) {\r
+ } else {\r
+ PCA_xt_by_x(this, u);// if(xt_by_x( input, u ) < 0 ) {\r
+ }\r
+ u.PCA_QRM(o_ev);\r
+\r
+ double[][] m1, m2;\r
+ if (l_row < l_clm) {\r
+ NyARException.trap("未チェックのパス");\r
+ PCA_EV_create(this, u, o_output, o_ev);\r
+ } else {\r
+ m1 = u._m;// m1 = u->m;\r
+ m2 = o_output._m;// m2 = output->m;\r
+ int i;\r
+ for (i = 0; i < min; i++) {\r
+ if (ev_array[i] < PCA_VZERO) {// if( ev->v[i] < VZERO ){\r
+ break;\r
+ }\r
+ for (int j = 0; j < min; j++) {\r
+ m2[i][j] = m1[i][j];// *(m2++) = *(m1++);\r
+ }\r
+ }\r
+ for (; i < min; i++) {// for( ; i < min; i++){\r
+ // コードを見た限りあってそうだからコメントアウト(2008/03/26)NyARException.trap("未チェックのパス");\r
+ ev_array[i] = 0.0;// ev->v[i] = 0.0;\r
+ for (int j = 0; j < min; j++) {\r
+ m2[i][j] = 0.0;// *(m2++) = 0.0;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ /**\r
+ * 主成分分析を実行して、結果をthisと引数へ格納します。\r
+ * @param o_evec\r
+ * @param o_ev\r
+ * @param o_mean\r
+ * @throws NyARException\r
+ */\r
+ public void pca(NyARMat o_evec, NyARVec o_ev, NyARVec o_mean)throws NyARException\r
+ {\r
+ final double l_row = this.row;// row = input->row;\r
+ final double l_clm = this.clm;// clm = input->clm;\r
+ final double check=(l_row < l_clm) ? l_row : l_clm;\r
+ \r
+ assert l_row >= 2 || l_clm >= 2;\r
+ assert o_evec.clm == l_clm && o_evec.row == check;\r
+ assert o_ev.getClm() == check;\r
+ assert o_mean.getClm() == l_clm;\r
+ \r
+ final double srow = Math.sqrt((double) l_row);\r
+ PCA_EX(o_mean);\r
+\r
+ PCA_CENTER(this, o_mean);\r
+\r
+ int i, j;\r
+ // For順変更OK\r
+ for (i = 0; i < l_row; i++) {\r
+ for (j = 0; j < l_clm; j++) {\r
+ this._m[i][j] /= srow;// work->m[i] /= srow;\r
+ }\r
+ }\r
+\r
+ PCA_PCA(o_evec, o_ev);\r
+\r
+ double sum = 0.0;\r
+ double[] ev_array = o_ev.getArray();\r
+ int ev_clm = o_ev.getClm();\r
+ // For順変更禁止\r
+ for (i = 0; i < ev_clm; i++) {// for(int i = 0; i < ev->clm; i++ ){\r
+ sum += ev_array[i];// sum += ev->v[i];\r
+ }\r
+ // For順変更禁止\r
+ for (i = 0; i < ev_clm; i++) {// for(int i = 0; i < ev->clm; i++ ){\r
+ ev_array[i] /= sum;// ev->v[i] /= sum;\r
+ }\r
+ return;\r
+ }\r
+ \r
+\r
+\r
+ private final NyARVec wk_vecTridiagonalize_vec = new NyARVec(0);\r
+\r
+ private final NyARVec wk_vecTridiagonalize_vec2 = new NyARVec(0);\r
+\r
+ /**\r
+ * arVecTridiagonalize関数の代替品 a,d,e間で演算をしてる。何をどうしているかはさっぱりさっぱり\r
+ * \r
+ * @param a\r
+ * @param d\r
+ * @param e\r
+ * @param i_e_start\r
+ * 演算開始列(よくわからないけどarVecTridiagonalizeの呼び出し元でなんかしてる)\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ private void vecTridiagonalize(NyARVec d, NyARVec e, int i_e_start)throws NyARException\r
+ {\r
+ NyARVec vec = wk_vecTridiagonalize_vec;\r
+ // double[][] a_array=a.getArray();\r
+ double s, t, p, q;\r
+ int dim;\r
+\r
+ if (this.clm != this.row) {// if(a.getClm()!=a.getRow()){\r
+ throw new NyARException();\r
+ }\r
+ if (this.clm != d.getClm()) {// if(a.getClm() != d.clm){\r
+ throw new NyARException();\r
+ }\r
+ if (this.clm != e.getClm()) {// if(a.getClm() != e.clm){\r
+ throw new NyARException();\r
+ }\r
+ dim = this.getClm();\r
+\r
+ double[] d_vec, e_vec;\r
+ d_vec = d.getArray();\r
+ e_vec = e.getArray();\r
+ double[] a_vec_k;\r
+\r
+ for (int k = 0; k < dim - 2; k++) {\r
+\r
+ a_vec_k = this._m[k];\r
+ vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);//double[]\r
+ // vec_array=vec.getArray();\r
+ NyARException.trap("未チェックパス");\r
+ d_vec[k] = a_vec_k[k];// d.v[k]=vec.v[k];//d.set(k,v.get(k));\r
+ // //d->v[k] = v[k];\r
+\r
+ // wv1.clm = dim-k-1;\r
+ // wv1.v = &(v[k+1]);\r
+ NyARException.trap("未チェックパス");\r
+ e_vec[k + i_e_start] = vec.vecHousehold(k + 1);// e.v[k+i_e_start]=vec.vecHousehold(k+1);//e->v[k]= arVecHousehold(&wv1);\r
+ if (e_vec[k + i_e_start] == 0.0) {// if(e.v[k+i_e_start]== 0.0){//if(e.v[k+i_e_start]== 0.0){\r
+ continue;\r
+ }\r
+\r
+ for (int i = k + 1; i < dim; i++) {\r
+ s = 0.0;\r
+ for (int j = k + 1; j < i; j++) {\r
+ NyARException.trap("未チェックのパス");\r
+ s += this._m[j][i] * a_vec_k[j];// s += a_array[j][i] *vec.v[j];//s +=a.get(j*dim+i) *v.get(j);//s +=a->m[j*dim+i] * v[j];\r
+ }\r
+ for (int j = i; j < dim; j++) {\r
+ NyARException.trap("未チェックのパス");\r
+ s += this._m[i][j] * a_vec_k[j];// s += a_array[i][j] *vec.v[j];//s +=a.get(i*dim+j) *v.get(j);//s +=a->m[i*dim+j] * v[j];\r
+ }\r
+ NyARException.trap("未チェックのパス");\r
+ d_vec[i] = s;// d.v[i]=s;//d->v[i] = s;\r
+ }\r
+\r
+ // wv1.clm = wv2.clm = dim-k-1;\r
+ // wv1.v = &(v[k+1]);\r
+ // wv2.v = &(d->v[k+1]);\r
+ a_vec_k = this._m[k];\r
+ vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);\r
+ // vec_array=vec.getArray();\r
+ NyARException.trap("未チェックパス");\r
+ t = vec.vecInnerproduct(d, k + 1) / 2;\r
+ for (int i = dim - 1; i > k; i--) {\r
+ NyARException.trap("未チェックパス");\r
+ p = a_vec_k[i];// p = v.get(i);//p = v[i];\r
+ d_vec[i] -= t * p;\r
+ q = d_vec[i];// d.v[i]-=t*p;q=d.v[i];//q = d->v[i] -= t*p;\r
+ for (int j = i; j < dim; j++) {\r
+ NyARException.trap("未チェックパス");\r
+ this._m[i][j] -= p * (d_vec[j] + q * a_vec_k[j]);// a.m[i][j]-=p*(d.v[j] +q*vec.v[j]);//a->m[i*dim+j] -=p*(d->v[j]) + q*v[j];\r
+ }\r
+ }\r
+ }\r
+\r
+ if (dim >= 2) {\r
+ d_vec[dim - 2] = this._m[dim - 2][dim - 2];// d.v[dim-2]=a.m[dim-2][dim-2];//d->v[dim-2]=a->m[(dim-2)*dim+(dim-2)];\r
+ e_vec[dim - 2 + i_e_start] = this._m[dim - 2][dim - 1];// e.v[dim-2+i_e_start]=a.m[dim-2][dim-1];//e->v[dim-2] = a->m[(dim-2)*dim+(dim-1)];\r
+ }\r
+\r
+ if (dim >= 1) {\r
+ d_vec[dim - 1] = this._m[dim - 1][dim - 1];// d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] =a->m[(dim-1)*dim+(dim-1)];\r
+ }\r
+ NyARVec vec2 = this.wk_vecTridiagonalize_vec2;\r
+ for (int k = dim - 1; k >= 0; k--) {\r
+ a_vec_k = this._m[k];\r
+ vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);//v =a.getPointer(k*dim);//v = &(a->m[k*dim]);\r
+ if (k < dim - 2) {\r
+ for (int i = k + 1; i < dim; i++) {\r
+ // wv1.clm = wv2.clm = dim-k-1;\r
+ // wv1.v = &(v[k+1]);\r
+ // wv2.v = &(a->m[i*dim+k+1]);\r
+ vec2.setNewArray(this._m[i], clm);// vec2=this.getRowVec(i);\r
+\r
+ t = vec.vecInnerproduct(vec2, k + 1);\r
+ for (int j = k + 1; j < dim; j++) {\r
+ NyARException.trap("未チェックパス");\r
+ this._m[i][j] -= t * a_vec_k[j];// a_array[i][j]-=t*vec.v[j];//a.subValue(i*dim+j,t*v.get(j));//a->m[i*dim+j]-= t * v[j];\r
+ }\r
+ }\r
+ }\r
+ for (int i = 0; i < dim; i++) {\r
+ a_vec_k[i] = 0.0;// v.set(i,0.0);//v[i] = 0.0;\r
+ }\r
+ a_vec_k[k] = 1;// v.set(k,1);//v[k] = 1;\r
+ }\r
+ return;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+public class NyARVec\r
+{\r
+ private int clm;\r
+\r
+ public NyARVec(int i_clm)\r
+ {\r
+ v = new double[i_clm];\r
+ clm = i_clm;\r
+ }\r
+\r
+ private double[] v;\r
+\r
+ /**\r
+ * i_clmサイズの列を格納できるように列サイズを変更します。 実行後、列の各値は不定になります。\r
+ * \r
+ * @param i_clm\r
+ */\r
+ public void realloc(int i_clm)\r
+ {\r
+ if (i_clm <= this.v.length) {\r
+ // 十分な配列があれば何もしない。\r
+ } else {\r
+ // 不十分なら取り直す。\r
+ v = new double[i_clm];\r
+ }\r
+ this.clm = i_clm;\r
+ }\r
+\r
+ public int getClm()\r
+ {\r
+ return clm;\r
+ }\r
+\r
+ public double[] getArray()\r
+ {\r
+ return v;\r
+ }\r
+\r
+ /**\r
+ * arVecDispの代替品\r
+ * \r
+ * @param value\r
+ * @return\r
+ */\r
+ public int arVecDisp() throws NyARException\r
+ {\r
+ NyARException.trap("未チェックのパス");\r
+ System.out.println(" === vector (" + clm + ") ===\n");// printf(" ===\r
+ // vector (%d)\r
+ // ===\n",\r
+ // v->clm);\r
+ System.out.print(" |");// printf(" |");\r
+ for (int c = 0; c < clm; c++) {// for( c = 0; c < v->clm; c++ ){\r
+ System.out.print(" " + v[c]);// printf( " %10g", v->v[c] );\r
+ }\r
+ System.out.println(" |");// printf(" |\n");\r
+ System.out.println(" ===================");// printf("\r
+ // ===================\n");\r
+ return 0;\r
+ }\r
+\r
+ /**\r
+ * arVecInnerproduct関数の代替品\r
+ * \r
+ * @param x\r
+ * @param y\r
+ * @param i_start\r
+ * 演算開始列(よくわからないけどarVecTridiagonalizeの呼び出し元でなんかしてる)\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double vecInnerproduct(NyARVec y, int i_start) throws NyARException\r
+ {\r
+ NyARException.trap("この関数は動作確認できていません。");\r
+ double result = 0.0;\r
+ // double[] x_array=x.v;.getArray();\r
+ // double[] y_array=y.getArray();\r
+\r
+ if (this.clm != y.clm) {\r
+ throw new NyARException();// exit();\r
+ }\r
+ for (int i = i_start; i < this.clm; i++) {\r
+ NyARException.trap("未チェックのパス");\r
+ result += this.v[i] * y.v[i];// result += x->v[i] * y->v[i];\r
+ }\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * double arVecHousehold関数の代替品\r
+ * \r
+ * @param x\r
+ * @param i_start\r
+ * 演算開始列(よくわからないけどarVecTridiagonalizeの呼び出し元でなんかしてる)\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double vecHousehold(int i_start) throws NyARException\r
+ {\r
+ NyARException.trap("この関数は動作確認できていません。");\r
+ double s, t;\r
+ s = Math.sqrt(this.vecInnerproduct(this, i_start));\r
+ // double[] x_array=x.getArray();\r
+ if (s != 0.0) {\r
+ NyARException.trap("未チェックのパス");\r
+ if (this.v[i_start] < 0) {\r
+ s = -s;\r
+ }\r
+ NyARException.trap("未チェックのパス");\r
+ {\r
+ this.v[i_start] += s;// x->v[0] += s;\r
+ t = 1 / Math.sqrt(this.v[i_start] * s);// t = 1 / sqrt(x->v[0] * s);\r
+ }\r
+ for (int i = i_start; i < this.clm; i++) {\r
+ NyARException.trap("未チェックのパス");\r
+ this.v[i] *= t;// x->v[i] *= t;\r
+ }\r
+ }\r
+ return -s;\r
+ }\r
+\r
+ /**\r
+ * 現在ラップしている配列を取り外して、新しい配列をラップします。\r
+ * \r
+ * @param i_v\r
+ * @param i_clm\r
+ */\r
+ public void setNewArray(double[] i_array, int i_clm)\r
+ {\r
+ this.v = i_array;\r
+ this.clm = i_clm;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core;\r
+\r
+/**\r
+ * ARUint32 arGetVersion(char **versionStringRef); 関数の置き換え\r
+ */\r
+public class NyARVersion\r
+{\r
+ private static final int AR_HEADER_VERSION_MAJOR = 2; // #define\r
+ // AR_HEADER_VERSION_MAJOR\r
+ // 2\r
+\r
+ private static final int AR_HEADER_VERSION_MINOR = 72;// #define AR_HEADER_VERSION_MINOR 72\r
+\r
+ private static final int AR_HEADER_VERSION_TINY = 0;// #define AR_HEADER_VERSION_TINY 0\r
+\r
+ private static final int AR_HEADER_VERSION_BUILD = 0;// #define AR_HEADER_VERSION_BUILD 0\r
+\r
+ private static final String AR_HEADER_VERSION_STRING = "2.72.0";// #define AR_HEADER_VERSION_STRING "2.72.0"\r
+\r
+ public static final boolean AR_HAVE_HEADER_VERSION_2 = true;// #define AR_HAVE_HEADER_VERSION_2\r
+\r
+ public static final boolean AR_HAVE_HEADER_VERSION_2_72 = true;// #define AR_HAVE_HEADER_VERSION_2_72\r
+\r
+ public static String getARVersion()\r
+ {\r
+ return AR_HEADER_VERSION_STRING;\r
+ }\r
+\r
+ public static int getARVersionInt()\r
+ {\r
+ // Represent full version number (major, minor, tiny, build) in\r
+ // binary coded decimal. N.B: Integer division.\r
+ return (int) (0x10000000 * (AR_HEADER_VERSION_MAJOR / 10))\r
+ + (int) (0x01000000 * (AR_HEADER_VERSION_MAJOR % 10))\r
+ + (int) (0x00100000 * (AR_HEADER_VERSION_MINOR / 10))\r
+ + (int) (0x00010000 * (AR_HEADER_VERSION_MINOR % 10))\r
+ + (int) (0x00001000 * (AR_HEADER_VERSION_TINY / 10))\r
+ + (int) (0x00000100 * (AR_HEADER_VERSION_TINY % 10))\r
+ + (int) (0x00000010 * (AR_HEADER_VERSION_BUILD / 10))\r
+ + (int) (0x00000001 * (AR_HEADER_VERSION_BUILD % 10));\r
+\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.analyzer.histgram;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistgram;\r
+\r
+public interface INyARHistgramAnalyzer_Threshold\r
+{\r
+ /**\r
+ * ヒストグラムから閾値探索をします。\r
+ * @param i_histgram\r
+ * ヒストグラム\r
+ * @return\r
+ */\r
+ public int getThreshold(NyARHistgram i_histgram);\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.analyzer.histgram;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistgram;\r
+\r
+/**\r
+ * 判別法で閾値を求めます。\r
+ * 画素数が2048^2に満たない場合は、fixedint(24-8)で計算できます。\r
+ * @param i_histgram\r
+ * @param o_value\r
+ * @return\r
+ */\r
+public class NyARHistgramAnalyzer_DiscriminantThreshold implements INyARHistgramAnalyzer_Threshold\r
+{\r
+ private double _score;\r
+\r
+\r
+ public int getThreshold(NyARHistgram i_histgram)\r
+ {\r
+ int[] hist=i_histgram.data;\r
+ int n=i_histgram.length;\r
+ int da,sa,db,sb,dt,pt,st;\r
+ int i; \r
+ int th=0;\r
+ //後で使う\r
+ dt=pt=0;\r
+ for(i=0;i<n;i++){\r
+ int h=hist[i];\r
+ dt+=h*i;\r
+ pt+=h*i*i;//正規化の時に使う定数\r
+ }\r
+ st=i_histgram.total_of_data;\r
+ //Low側(0<=i<=n-2)\r
+ da=dt;\r
+ sa=st;\r
+ //High側(i=n-1)\r
+ db=sb=0; \r
+ \r
+ double max=-1;\r
+ double max_mt=0;\r
+ //各ヒストグラムの分離度を計算する(1<=i<=n-1の範囲で評価)\r
+ for(i=n-1;i>0;i--){\r
+ //次のヒストグラムを計算\r
+ int hist_count=hist[i];\r
+ int hist_val=hist_count*i;\r
+ da-=hist_val;\r
+ sa-=hist_count;\r
+ db+=hist_val;\r
+ sb+=hist_count;\r
+ \r
+ //クラス間分散を計算\r
+ double dv=(sa+sb);\r
+ double mt=(double)(da+db)/dv;\r
+ double ma=(sa!=0?((double)da/(double)sa):0)-mt;\r
+ double mb=(sb!=0?((double)db/(double)sb):0)-mt;\r
+ double kai=((double)(sa*(ma*ma)+sb*(mb*mb)))/dv;\r
+ if(max<kai){\r
+ max_mt=mt;\r
+ max=kai;\r
+ th=i;\r
+ }\r
+ //System.out.println(kai);\r
+ }\r
+ //max_mtを元に正規化\r
+ this._score=max/((double)(pt+max_mt*max_mt*st-2*max_mt*dt)/st);//129,0.8888888888888887\r
+ return th;\r
+ }\r
+ /**\r
+ * 最後に実行したgetThresholdのスコアを返します。\r
+ * スコアは正規化された分離度。1.0-0.0の範囲を取る。0.7以上なら概ね双峰的です。\r
+ * @return\r
+ */\r
+ public final double getLastScore()\r
+ {\r
+ return this._score;\r
+ }\r
+ /**\r
+ * Debug\r
+ */\r
+ public static void main(String[] args)\r
+ {\r
+ NyARHistgram data=new NyARHistgram(256);\r
+ for(int i=0;i<256;i++){\r
+ data.data[i]=128-i>0?128-i:i-128;\r
+ }\r
+ data.total_of_data=data.getTotal(0,255);\r
+ NyARHistgramAnalyzer_DiscriminantThreshold an=new NyARHistgramAnalyzer_DiscriminantThreshold();\r
+ int th=an.getThreshold(data);\r
+ System.out.print(th);\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.analyzer.histgram;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistgram;\r
+\r
+\r
+/**\r
+ * kittlerThresholdの方式で閾値を求めます。\r
+ * @param i_histgram\r
+ * @return\r
+ */\r
+public class NyARHistgramAnalyzer_KittlerThreshold implements INyARHistgramAnalyzer_Threshold\r
+{\r
+ public int getThreshold(NyARHistgram i_histgram)\r
+ {\r
+ int i; \r
+ double min=Double.MAX_VALUE;\r
+ int th=0;\r
+ int da,sa,db,sb,pa,pb;\r
+ double oa,ob;\r
+ \r
+ int[] hist=i_histgram.data;\r
+ int n=i_histgram.length;\r
+ //Low側\r
+ da=pa=0;\r
+ int h;\r
+ for(i=0;i<n;i++){\r
+ h=hist[i];\r
+ da+=h*i; //i*h[i]\r
+ pa+=h*i*i; //i*i*h[i]\r
+ }\r
+ sa=i_histgram.total_of_data;\r
+ //High側(i=n-1)\r
+ db=0;\r
+ sb=0;\r
+ pb=0;\r
+ \r
+ \r
+ for(i=n-1;i>0;i--){\r
+ //次のヒストグラムを計算\r
+ int hist_count=hist[i];//h[i]\r
+ int hist_val =hist_count*i; //h[i]*i\r
+ int hist_val2=hist_val*i; //h[i]*i*i\r
+ da-=hist_val;\r
+ sa-=hist_count;\r
+ pa-=hist_val2;\r
+ db+=hist_val;\r
+ sb+=hist_count; \r
+ pb+=hist_val2;\r
+\r
+ //初期化\r
+ double wa=(double)sa/(sa+sb);\r
+ double wb=(double)sb/(sa+sb);\r
+ if(wa==0 || wb==0){\r
+ continue;\r
+ }\r
+\r
+ oa=ob=0;\r
+ double ma=sa!=0?(double)da/sa:0;\r
+ //Σ(i-ma)^2*h[i]=Σ(i^2*h[i])+Σ(ma^2*h[i])-Σ(2*i*ma*h[i])\r
+ oa=((double)(pa+ma*ma*sa-2*ma*da))/sa;\r
+\r
+ double mb=sb!=0?(double)db/sb:0;\r
+ //Σ(i-mb)^2*h[i]=Σ(i^2*h[i])+Σ(mb^2*h[i])-Σ(2*i*mb*h[i])\r
+ ob=((double)(pb+mb*mb*sb-2*mb*db))/sb;\r
+\r
+ double kai=wa*Math.log(oa/wa)+wb*Math.log(ob/wb);\r
+ if(kai>0 && min>kai){\r
+ min=kai;\r
+ th=i;\r
+ }\r
+ //System.out.println(kai);\r
+\r
+ }\r
+ return th;//129//7.506713872738873\r
+ }\r
+ public static void main(String[] args)\r
+ {\r
+ NyARHistgram data=new NyARHistgram(256);\r
+ for(int i=0;i<256;i++){\r
+ data.data[i]=128-i>0?128-i:i-128;\r
+ }\r
+ data.total_of_data=data.getTotal(0,255);\r
+ NyARHistgramAnalyzer_KittlerThreshold an=new NyARHistgramAnalyzer_KittlerThreshold();\r
+ int th=an.getThreshold(data);\r
+ System.out.print(th);\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.analyzer.histgram;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistgram;\r
+\r
+\r
+\r
+/**\r
+ * 明点と暗点を双方向からPタイル法でカウントして、その中央値を閾値とする。\r
+ * \r
+ * \r
+ */\r
+public class NyARHistgramAnalyzer_SlidePTile implements INyARHistgramAnalyzer_Threshold\r
+{\r
+ private int _persentage;\r
+ public NyARHistgramAnalyzer_SlidePTile(int i_persentage)\r
+ {\r
+ assert (0 <= i_persentage && i_persentage <= 50);\r
+ //初期化\r
+ this._persentage=i_persentage;\r
+ } \r
+ public int getThreshold(NyARHistgram i_histgram)\r
+ {\r
+ //総ピクセル数を計算\r
+ int n=i_histgram.length;\r
+ int sum_of_pixel=i_histgram.total_of_data;\r
+ int[] hist=i_histgram.data;\r
+ // 閾値ピクセル数確定\r
+ final int th_pixcels = sum_of_pixel * this._persentage / 100;\r
+ int th_wk;\r
+ int th_w, th_b;\r
+\r
+ // 黒点基準\r
+ th_wk = th_pixcels;\r
+ for (th_b = 0; th_b < n-2; th_b++) {\r
+ th_wk -= hist[th_b];\r
+ if (th_wk <= 0) {\r
+ break;\r
+ }\r
+ }\r
+ // 白点基準\r
+ th_wk = th_pixcels;\r
+ for (th_w = n-1; th_w > 1; th_w--) {\r
+ th_wk -= hist[th_w];\r
+ if (th_wk <= 0) {\r
+ break;\r
+ }\r
+ }\r
+ // 閾値の保存\r
+ return (th_w + th_b) / 2;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.analyzer.raster;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistgram;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.analyzer.histgram.*;\r
+/**\r
+ * 画像のヒストグラムを計算します。\r
+ * RGBの場合、(R+G+B)/3のヒストグラムを計算します。\r
+ * \r
+ * \r
+ */\r
+public class NyARRasterAnalyzer_Histgram\r
+{\r
+ private ICreateHistgramImpl _histImpl;\r
+ /**\r
+ * ヒストグラム解析の縦方向スキップ数。継承クラスはこのライン数づつ\r
+ * スキップしながらヒストグラム計算を行うこと。\r
+ */\r
+ protected int _vertical_skip;\r
+ \r
+ \r
+ public NyARRasterAnalyzer_Histgram(int i_raster_format,int i_vertical_interval) throws NyARException\r
+ {\r
+ switch (i_raster_format) {\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ this._histImpl = new NyARRasterThresholdAnalyzer_Histgram_BYTE1D_RGB_24();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8:\r
+ this._histImpl = new NyARRasterThresholdAnalyzer_Histgram_INT1D_GRAY_8();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32:\r
+ this._histImpl = new NyARRasterThresholdAnalyzer_Histgram_BYTE1D_B8G8R8X8_32();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_X8R8G8B8_32:\r
+ this._histImpl = new NyARRasterThresholdAnalyzer_Histgram_BYTE1D_X8R8G8B8_32();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_WORD1D_R5G6B5_16LE:\r
+ this._histImpl = new NyARRasterThresholdAnalyzer_Histgram_WORD1D_R5G6B5_16LE();\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ //初期化\r
+ this._vertical_skip=i_vertical_interval;\r
+ } \r
+ public void setVerticalInterval(int i_step)\r
+ {\r
+ this._vertical_skip=i_step;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * o_histgramにヒストグラムを出力します。\r
+ * @param i_input\r
+ * @param o_histgram\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int analyzeRaster(INyARRaster i_input,NyARHistgram o_histgram) throws NyARException\r
+ {\r
+ \r
+ final NyARIntSize size=i_input.getSize();\r
+ //最大画像サイズの制限\r
+ assert size.w*size.h<0x40000000;\r
+ assert o_histgram.length==256;//現在は固定\r
+\r
+ int[] h=o_histgram.data;\r
+ //ヒストグラム初期化\r
+ for (int i = o_histgram.length-1; i >=0; i--){\r
+ h[i] = 0;\r
+ }\r
+ o_histgram.total_of_data=size.w*size.h/this._vertical_skip;\r
+ return this._histImpl.createHistgram(i_input.getBufferReader(), size,h,this._vertical_skip); \r
+ }\r
+ \r
+ interface ICreateHistgramImpl\r
+ {\r
+ public int createHistgram(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram,int i_skip);\r
+ }\r
+\r
+ class NyARRasterThresholdAnalyzer_Histgram_INT1D_GRAY_8 implements ICreateHistgramImpl\r
+ {\r
+ public int createHistgram(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram,int i_skip)\r
+ {\r
+ assert (i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ final int[] input=(int[]) i_reader.getBuffer();\r
+ for (int y = i_size.h-1; y >=0 ; y-=i_skip){\r
+ int pt=y*i_size.w;\r
+ for (int x = i_size.w-1; x >=0; x--) {\r
+ o_histgram[input[pt]]++;\r
+ pt++;\r
+ }\r
+ }\r
+ return i_size.w*i_size.h;\r
+ } \r
+ }\r
+\r
+ class NyARRasterThresholdAnalyzer_Histgram_BYTE1D_RGB_24 implements ICreateHistgramImpl\r
+ {\r
+ public int createHistgram(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram,int i_skip)\r
+ {\r
+ assert (\r
+ i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24)||\r
+ i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24));\r
+ final byte[] input=(byte[]) i_reader.getBuffer();\r
+ final int pix_count=i_size.w;\r
+ final int pix_mod_part=pix_count-(pix_count%8);\r
+ for (int y = i_size.h-1; y >=0 ; y-=i_skip) {\r
+ int pt=y*i_size.w*3;\r
+ int x,v;\r
+ for (x = pix_count-1; x >=pix_mod_part; x--) {\r
+ v=((input[pt+0]& 0xff)+(input[pt+1]& 0xff)+(input[pt+2]& 0xff))/3;\r
+ o_histgram[v]++;\r
+ pt+=3;\r
+ }\r
+ //タイリング\r
+ for (;x>=0;x-=8){\r
+ v=((input[pt+ 0]& 0xff)+(input[pt+ 1]& 0xff)+(input[pt+ 2]& 0xff))/3;\r
+ o_histgram[v]++;\r
+ v=((input[pt+ 3]& 0xff)+(input[pt+ 4]& 0xff)+(input[pt+ 5]& 0xff))/3;\r
+ o_histgram[v]++;\r
+ v=((input[pt+ 6]& 0xff)+(input[pt+ 7]& 0xff)+(input[pt+ 8]& 0xff))/3;\r
+ o_histgram[v]++;\r
+ v=((input[pt+ 9]& 0xff)+(input[pt+10]& 0xff)+(input[pt+11]& 0xff))/3;\r
+ o_histgram[v]++;\r
+ v=((input[pt+12]& 0xff)+(input[pt+13]& 0xff)+(input[pt+14]& 0xff))/3;\r
+ o_histgram[v]++;\r
+ v=((input[pt+15]& 0xff)+(input[pt+16]& 0xff)+(input[pt+17]& 0xff))/3;\r
+ o_histgram[v]++;\r
+ v=((input[pt+18]& 0xff)+(input[pt+19]& 0xff)+(input[pt+20]& 0xff))/3;\r
+ o_histgram[v]++;\r
+ v=((input[pt+21]& 0xff)+(input[pt+22]& 0xff)+(input[pt+23]& 0xff))/3;\r
+ o_histgram[v]++;\r
+ pt+=3*8;\r
+ }\r
+ }\r
+ return i_size.w*i_size.h;\r
+ }\r
+ }\r
+\r
+ class NyARRasterThresholdAnalyzer_Histgram_BYTE1D_B8G8R8X8_32 implements ICreateHistgramImpl\r
+ {\r
+ public int createHistgram(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram,int i_skip)\r
+ {\r
+ assert(i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32));\r
+ byte[] input = (byte[])i_reader.getBuffer();\r
+ int pix_count = i_size.w;\r
+ int pix_mod_part = pix_count - (pix_count % 8);\r
+ for (int y = i_size.h - 1; y >= 0; y -= i_skip)\r
+ {\r
+ int pt = y * i_size.w * 4;\r
+ int x, v;\r
+ for (x = pix_count - 1; x >= pix_mod_part; x--)\r
+ {\r
+ v = ((input[pt + 0] & 0xff) + (input[pt + 1] & 0xff) + (input[pt + 2] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ pt += 4;\r
+ }\r
+ //タイリング\r
+ for (; x >= 0; x -= 8)\r
+ {\r
+ v = ((input[pt + 0] & 0xff) + (input[pt + 1] & 0xff) + (input[pt + 2] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 4] & 0xff) + (input[pt + 5] & 0xff) + (input[pt + 6] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 8] & 0xff) + (input[pt + 9] & 0xff) + (input[pt + 10] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 12] & 0xff) + (input[pt + 13] & 0xff) + (input[pt + 14] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 16] & 0xff) + (input[pt + 17] & 0xff) + (input[pt + 18] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 20] & 0xff) + (input[pt + 21] & 0xff) + (input[pt + 22] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 24] & 0xff) + (input[pt + 25] & 0xff) + (input[pt + 26] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 28] & 0xff) + (input[pt + 29] & 0xff) + (input[pt + 30] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ pt += 4 * 8;\r
+ }\r
+ }\r
+ return i_size.w*i_size.h;\r
+ }\r
+ }\r
+\r
+ class NyARRasterThresholdAnalyzer_Histgram_BYTE1D_X8R8G8B8_32 implements ICreateHistgramImpl\r
+ {\r
+ public int createHistgram(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram,int i_skip)\r
+ {\r
+ assert(i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_X8R8G8B8_32));\r
+ byte[] input = (byte[])i_reader.getBuffer();\r
+ int pix_count = i_size.w;\r
+ int pix_mod_part = pix_count - (pix_count % 8);\r
+ for (int y = i_size.h - 1; y >= 0; y -=i_skip)\r
+ {\r
+ int pt = y * i_size.w * 4;\r
+ int x, v;\r
+ for (x = pix_count - 1; x >= pix_mod_part; x--)\r
+ {\r
+ v = ((input[pt + 1] & 0xff) + (input[pt + 2] & 0xff) + (input[pt + 3] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ pt += 4;\r
+ }\r
+ //タイリング\r
+ for (; x >= 0; x -= 8)\r
+ {\r
+ v = ((input[pt + 1] & 0xff) + (input[pt + 2] & 0xff) + (input[pt + 3] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 5] & 0xff) + (input[pt + 6] & 0xff) + (input[pt + 7] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 9] & 0xff) + (input[pt + 10] & 0xff) + (input[pt + 11] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 13] & 0xff) + (input[pt + 14] & 0xff) + (input[pt + 15] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 17] & 0xff) + (input[pt + 18] & 0xff) + (input[pt + 19] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 21] & 0xff) + (input[pt + 22] & 0xff) + (input[pt + 23] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 25] & 0xff) + (input[pt + 26] & 0xff) + (input[pt + 27] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ v = ((input[pt + 29] & 0xff) + (input[pt + 30] & 0xff) + (input[pt + 31] & 0xff)) / 3;\r
+ o_histgram[v]++;\r
+ pt += 4 * 8;\r
+ }\r
+ }\r
+ return i_size.w*i_size.h;\r
+ }\r
+ }\r
+\r
+ class NyARRasterThresholdAnalyzer_Histgram_WORD1D_R5G6B5_16LE implements ICreateHistgramImpl\r
+ {\r
+ public int createHistgram(INyARBufferReader i_reader,NyARIntSize i_size, int[] o_histgram,int i_skip)\r
+ {\r
+ assert(i_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_WORD1D_R5G6B5_16LE));\r
+ short[] input = (short[])i_reader.getBuffer();\r
+ int pix_count = i_size.w;\r
+ int pix_mod_part = pix_count - (pix_count % 8);\r
+ for (int y = i_size.h - 1; y >= 0; y -= i_skip)\r
+ {\r
+ int pt = y * i_size.w;\r
+ int x, v;\r
+ for (x = pix_count - 1; x >= pix_mod_part; x--)\r
+ {\r
+ v =(int)input[pt];\r
+ v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
+ o_histgram[v]++;\r
+ pt++;\r
+ }\r
+ //タイリング\r
+ for (; x >= 0; x -= 8)\r
+ {\r
+ v =(int)input[pt];pt++;\r
+ v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
+ o_histgram[v]++;\r
+ v =(int)input[pt];pt++;\r
+ v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
+ o_histgram[v]++;\r
+ v =(int)input[pt];pt++;\r
+ v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
+ o_histgram[v]++;\r
+ v =(int)input[pt];pt++;\r
+ v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
+ o_histgram[v]++;\r
+ v =(int)input[pt];pt++;\r
+ v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
+ o_histgram[v]++;\r
+ v =(int)input[pt];pt++;\r
+ v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
+ o_histgram[v]++;\r
+ v =(int)input[pt];pt++;\r
+ v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
+ o_histgram[v]++;\r
+ v =(int)input[pt];pt++;\r
+ v = (((v & 0xf800) >> 8) + ((v & 0x07e0) >> 3) + ((v & 0x001f) << 3))/3;\r
+ o_histgram[v]++;\r
+ }\r
+ }\r
+ return i_size.w*i_size.h;\r
+ }\r
+ }\r
+\r
+\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.analyzer.raster.threshold;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+public interface INyARRasterThresholdAnalyzer\r
+{\r
+ public int analyzeRaster(INyARRaster i_input) throws NyARException;\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.analyzer.raster.threshold;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.analyzer.histgram.*;\r
+import jp.nyatla.nyartoolkit.core.analyzer.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistgram;\r
+/**\r
+ * 明点と暗点をPタイル法で検出して、その中央値を閾値とする。\r
+ * \r
+ * \r
+ */\r
+public class NyARRasterThresholdAnalyzer_SlidePTile implements INyARRasterThresholdAnalyzer\r
+{\r
+ private NyARRasterAnalyzer_Histgram _raster_analyzer;\r
+ private NyARHistgramAnalyzer_SlidePTile _sptile;\r
+ private NyARHistgram _histgram;\r
+ public void setVerticalInterval(int i_step)\r
+ {\r
+ this._raster_analyzer.setVerticalInterval(i_step);\r
+ return;\r
+ }\r
+ public NyARRasterThresholdAnalyzer_SlidePTile(int i_persentage,int i_raster_format,int i_vertical_interval) throws NyARException\r
+ {\r
+ assert (0 <= i_persentage && i_persentage <= 50);\r
+ //初期化\r
+ this._sptile=new NyARHistgramAnalyzer_SlidePTile(i_persentage);\r
+ this._histgram=new NyARHistgram(256);\r
+ this._raster_analyzer=new NyARRasterAnalyzer_Histgram(i_raster_format,i_vertical_interval);\r
+ }\r
+ \r
+ public int analyzeRaster(INyARRaster i_input) throws NyARException\r
+ {\r
+ this._raster_analyzer.analyzeRaster(i_input, this._histgram);\r
+ return this._sptile.getThreshold(this._histgram);\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling;\r
+\r
+import java.lang.reflect.Array;\r
+\r
+\r
+/**\r
+ * ラベル同士の重なり(内包関係)を調べるクラスです。 \r
+ * ラベルリストに内包するラベルを蓄積し、それにターゲットのラベルが内包されているか を確認します。\r
+ */\r
+public class LabelOverlapChecker<T extends NyARLabelInfo>\r
+{\r
+ private T[] _labels;\r
+ private int _length;\r
+ private Class<T> _element_type;\r
+ /*\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ public LabelOverlapChecker(int i_max_label,Class<T> i_element_type)\r
+ {\r
+ this._element_type=i_element_type;\r
+ this._labels = (T[])Array.newInstance(i_element_type, i_max_label);\r
+ }\r
+\r
+ /**\r
+ * チェック対象のラベルを追加する。\r
+ * \r
+ * @param i_label_ref\r
+ */\r
+ public void push(T i_label_ref)\r
+ {\r
+ this._labels[this._length] = i_label_ref;\r
+ this._length++;\r
+ }\r
+\r
+ /**\r
+ * 現在リストにあるラベルと重なっているかを返す。\r
+ * \r
+ * @param i_label\r
+ * @return 何れかのラベルの内側にあるならばfalse,独立したラベルである可能性が高ければtrueです.\r
+ */\r
+ public boolean check(T i_label)\r
+ {\r
+ // 重なり処理かな?\r
+ final T[] label_pt = this._labels;\r
+ final int px1 = (int) i_label.pos_x;\r
+ final int py1 = (int) i_label.pos_y;\r
+ for (int i = this._length - 1; i >= 0; i--) {\r
+ final int px2 = (int) label_pt[i].pos_x;\r
+ final int py2 = (int) label_pt[i].pos_y;\r
+ final int d = (px1 - px2) * (px1 - px2) + (py1 - py2) * (py1 - py2);\r
+ if (d < label_pt[i].area / 4) {\r
+ // 対象外\r
+ return false;\r
+ }\r
+ }\r
+ // 対象\r
+ return true;\r
+ }\r
+ /**\r
+ * 最大i_max_label個のラベルを蓄積できるようにオブジェクトをリセットする\r
+ * \r
+ * @param i_max_label\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ public void setMaxLabels(int i_max_label)\r
+ {\r
+ if (i_max_label > this._labels.length) {\r
+ this._labels = (T[])Array.newInstance(this._element_type, i_max_label);\r
+ }\r
+ this._length = 0;\r
+ } \r
+ \r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling;\r
+\r
+/**\r
+ * \r
+ *\r
+ */\r
+public class NyARLabelInfo\r
+{\r
+ public int area;\r
+ public int clip_r;\r
+ public int clip_l;\r
+ public int clip_b;\r
+ public int clip_t;\r
+ public double pos_x;\r
+ public double pos_y;\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.types.stack.NyObjectStack;\r
+\r
+/**\r
+ * NyLabelの予約型動的配列\r
+ * \r
+ */\r
+public abstract class NyARLabelInfoStack<T extends NyARLabelInfo> extends NyObjectStack<T>\r
+{\r
+ public NyARLabelInfoStack(int i_length,Class<T> i_element_type)\r
+ {\r
+ super(i_length,i_element_type);\r
+ }\r
+ \r
+ /**\r
+ * エリアの大きい順にラベルをソートします。\r
+ */\r
+ final public void sortByArea()\r
+ {\r
+ int len=this._length;\r
+ if(len<1){\r
+ return;\r
+ }\r
+ int h = len *13/10;\r
+ T[] item=this._items;\r
+ for(;;){\r
+ int swaps = 0;\r
+ for (int i = 0; i + h < len; i++) {\r
+ if (item[i + h].area > item[i].area) {\r
+ final T temp = item[i + h];\r
+ item[i + h] = item[i];\r
+ item[i] = temp;\r
+ swaps++;\r
+ }\r
+ }\r
+ if (h == 1) {\r
+ if (swaps == 0){\r
+ break;\r
+ }\r
+ }else{\r
+ h=h*10/13;\r
+ }\r
+ } \r
+ }\r
+}\r
+ \r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.artoolkit;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.NyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ *\r
+ */\r
+public class NyARLabelingImage extends NyARRaster_BasicClass\r
+{\r
+ private final static int MAX_LABELS = 1024*32; \r
+ protected int[] _ref_buf;\r
+ private INyARBufferReader _buffer_reader;\r
+ protected NyARLabelingLabelStack _label_list;\r
+ protected int[] _index_table;\r
+ protected boolean _is_index_table_enable;\r
+ public NyARLabelingImage(int i_width, int i_height)\r
+ {\r
+ super(new NyARIntSize(i_width,i_height));\r
+ this._ref_buf =new int[i_height*i_width];\r
+ this._label_list = new NyARLabelingLabelStack(MAX_LABELS);\r
+ this._index_table=new int[MAX_LABELS];\r
+ this._is_index_table_enable=false;\r
+ this._buffer_reader=new NyARBufferReader(this._ref_buf,INyARBufferReader.BUFFERFORMAT_INT1D);\r
+ //生成時に枠を書きます。\r
+ drawFrameEdge();\r
+ return;\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buffer_reader;\r
+ }\r
+ /**\r
+ * エッジを書きます。\r
+ */\r
+ public void drawFrameEdge()\r
+ {\r
+ int w=this._size.w;\r
+ int h=this._size.h;\r
+ // NyLabelingImageのイメージ初期化(枠書き)\r
+ int[] img = (int[]) this._ref_buf;\r
+ int bottom_ptr = (h - 1) * w;\r
+ for (int i = 0; i < w; i++) {\r
+ img[i] = 0;\r
+ img[bottom_ptr + i] = 0;\r
+ }\r
+ for (int i = 0; i < h; i++) {\r
+ img[i * w] = 0;\r
+ img[(i + 1) * w - 1] = 0;\r
+ }\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * ラベリング結果がインデックステーブルを持つ場合、その配列を返します。\r
+ * 持たない場合、nullを返します。\r
+ * \r
+ * 値がnullの時はラベル番号そのものがラスタに格納されていますが、\r
+ * null以外の時はラスタに格納されているのはインデクス番号です。\r
+ * \r
+ * インデクス番号とラベル番号の関係は、以下の式で表されます。\r
+ * ラベル番号:=value[インデクス番号]\r
+ * \r
+ */\r
+ public int[] getIndexArray()\r
+ {\r
+ return this._is_index_table_enable?this._index_table:null;\r
+ }\r
+ \r
+ public NyARLabelingLabelStack getLabelStack()\r
+ {\r
+ return this._label_list;\r
+ }\r
+ public void reset(boolean i_label_index_enable)\r
+ {\r
+ assert(i_label_index_enable==true);//非ラベルモードは未実装\r
+ this._label_list.clear();\r
+ this._is_index_table_enable=i_label_index_enable;\r
+ return;\r
+ }\r
+ //巡回参照できるように、テーブルを二重化\r
+ // 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6\r
+ protected final static int[] _getContour_xdir = { 0, 1, 1, 1, 0,-1,-1,-1 , 0, 1, 1, 1, 0,-1,-1};\r
+ protected final static int[] _getContour_ydir = {-1,-1, 0, 1, 1, 1, 0,-1 ,-1,-1, 0, 1, 1, 1, 0};\r
+ /**\r
+ * i_labelのラベルの、クリップ領域が上辺に接しているx座標を返します。\r
+ * @param i_index\r
+ * @return\r
+ */\r
+ public int getTopClipTangentX(NyARLabelingLabel i_label) throws NyARException\r
+ {\r
+ int pix;\r
+ int i_label_id=i_label.id;\r
+ int[] index_table=this._index_table;\r
+ int[] limage=this._ref_buf;\r
+ int limage_ptr=i_label.clip_t*this._size.w;\r
+ final int clip1 = i_label.clip_r;\r
+ // p1=ShortPointer.wrap(limage,j*xsize+clip.get());//p1 =&(limage[j*xsize+clip[0]]);\r
+ for (int i = i_label.clip_l; i <= clip1; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {\r
+ pix = limage[limage_ptr+i];\r
+ if (pix > 0 && index_table[pix-1] == i_label_id){\r
+ return i;\r
+ }\r
+ }\r
+ //あれ?見つからないよ?\r
+ throw new NyARException();\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.artoolkit;\r
+\r
+import jp.nyatla.nyartoolkit.core.labeling.*;\r
+/**\r
+ * [[Strage class]]\r
+ *\r
+ */\r
+public class NyARLabelingLabel extends NyARLabelInfo\r
+{\r
+ public int id; // フラグメントラベルのインデクス\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.artoolkit;\r
+\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.labeling.*;\r
+\r
+/**\r
+ * NyLabelの予約型動的配列\r
+ * \r
+ */\r
+public class NyARLabelingLabelStack extends NyARLabelInfoStack<NyARLabelingLabel>\r
+{\r
+ public NyARLabelingLabelStack(int i_max_array_size)\r
+ {\r
+ super(i_max_array_size,NyARLabelingLabel.class);\r
+ }\r
+ protected NyARLabelingLabel createElement()\r
+ {\r
+ return new NyARLabelingLabel();\r
+ } \r
+}\r
+ \r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.artoolkit;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * ARToolKit互換のラベリングクラスです。 ARToolKitと同一な評価結果を返します。\r
+ * \r
+ */\r
+final public class NyARLabeling_ARToolKit\r
+{\r
+ private static final int WORK_SIZE = 1024 * 32;// #define WORK_SIZE 1024*32\r
+\r
+ private final NyARWorkHolder work_holder = new NyARWorkHolder(WORK_SIZE);\r
+\r
+\r
+ /**\r
+ * static ARInt16 *labeling2( ARUint8 *image, int thresh,int *label_num, int **area, double **pos, int **clip,int **label_ref, int LorR ) 関数の代替品\r
+ * ラスタimageをラベリングして、結果を保存します。 Optimize:STEP[1514->1493]\r
+ * \r
+ * @param i_raster\r
+ * @throws NyARException\r
+ */\r
+ public int labeling(NyARBinRaster i_raster,NyARLabelingImage o_destination) throws NyARException\r
+ {\r
+ int label_img_ptr1, label_pixel;\r
+ int i, j;\r
+ int n, k; /* work */\r
+ \r
+ // サイズチェック\r
+ NyARIntSize in_size = i_raster.getSize();\r
+ assert(o_destination.getSize().isEqualSize(in_size));\r
+\r
+ final int lxsize = in_size.w;// lxsize = arUtil_c.arImXsize;\r
+ final int lysize = in_size.h;// lysize = arUtil_c.arImYsize;\r
+ final int[] label_img = (int[]) o_destination.getBufferReader().getBuffer();\r
+\r
+ // 枠作成はインスタンスを作った直後にやってしまう。\r
+\r
+ // ラベリング情報のリセット(ラベリングインデックスを使用)\r
+ o_destination.reset(true);\r
+\r
+ int[] label_idxtbl = o_destination.getIndexArray();\r
+ int[] raster_buf = (int[]) i_raster.getBufferReader().getBuffer();\r
+\r
+ int[] work2_pt;\r
+ int wk_max = 0;\r
+\r
+ int pixel_index;\r
+ int[][] work2 = this.work_holder.work2;\r
+\r
+ // [1,1](ptr0)と、[0,1](ptr1)のインデクス値を計算する。\r
+ for (j = 1; j < lysize - 1; j++) {// for (int j = 1; j < lysize - 1;j++, pnt += poff*2, pnt2 += 2) {\r
+ pixel_index = j * lxsize + 1;\r
+ label_img_ptr1 = pixel_index - lxsize;// label_img_pt1 = label_img[j - 1];\r
+ for (i = 1; i < lxsize - 1; i++, pixel_index++, label_img_ptr1++) {// for(int i = 1; i < lxsize-1;i++, pnt+=poff, pnt2++) {\r
+ // RGBの合計値が閾値より小さいかな?\r
+ if (raster_buf[pixel_index] != 0) {\r
+ label_img[pixel_index] = 0;// label_img_pt0[i] = 0;// *pnt2 = 0;\r
+ } else {\r
+ // pnt1 = ShortPointer.wrap(pnt2, -lxsize);//pnt1 =&(pnt2[-lxsize]);\r
+ if (label_img[label_img_ptr1] > 0) {// if (label_img_pt1[i] > 0) {// if( *pnt1 > 0 ) {\r
+ label_pixel = label_img[label_img_ptr1];// label_pixel = label_img_pt1[i];// *pnt2 = *pnt1;\r
+\r
+ work2_pt = work2[label_pixel - 1];\r
+ work2_pt[0]++;// work2[((*pnt2)-1)*7+0] ++;\r
+ work2_pt[1] += i;// work2[((*pnt2)-1)*7+1] += i;\r
+ work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j;\r
+ work2_pt[6] = j;// work2[((*pnt2)-1)*7+6] = j;\r
+ } else if (label_img[label_img_ptr1 + 1] > 0) {// } else if (label_img_pt1[i + 1] > 0) {// }else if(*(pnt1+1) > 0 ) {\r
+ if (label_img[label_img_ptr1 - 1] > 0) {// if (label_img_pt1[i - 1] > 0) {// if( *(pnt1-1) > 0 ) {\r
+ label_pixel = label_idxtbl[label_img[label_img_ptr1 + 1] - 1];// m = label_idxtbl[label_img_pt1[i + 1] - 1];// m\r
+ // =work[*(pnt1+1)-1];\r
+ n = label_idxtbl[label_img[label_img_ptr1 - 1] - 1];// n = label_idxtbl[label_img_pt1[i - 1] - 1];// n =work[*(pnt1-1)-1];\r
+ if (label_pixel > n) {\r
+ // wk=IntPointer.wrap(work, 0);//wk = &(work[0]);\r
+ for (k = 0; k < wk_max; k++) {\r
+ if (label_idxtbl[k] == label_pixel) {// if( *wk == m )\r
+ label_idxtbl[k] = n;// *wk = n;\r
+ }\r
+ }\r
+ label_pixel = n;// *pnt2 = n;\r
+ } else if (label_pixel < n) {\r
+ // wk=IntPointer.wrap(work,0);//wk = &(work[0]);\r
+ for (k = 0; k < wk_max; k++) {\r
+ if (label_idxtbl[k] == n) {// if( *wk == n ){\r
+ label_idxtbl[k] = label_pixel;// *wk = m;\r
+ }\r
+ }\r
+ }\r
+ work2_pt = work2[label_pixel - 1];\r
+ work2_pt[0]++;\r
+ work2_pt[1] += i;\r
+ work2_pt[2] += j;\r
+ work2_pt[6] = j;\r
+ } else if ((label_img[pixel_index - 1]) > 0) {// } else if ((label_img_pt0[i - 1]) > 0) {// }else if(*(pnt2-1) > 0) {\r
+ label_pixel = label_idxtbl[label_img[label_img_ptr1 + 1] - 1];// m = label_idxtbl[label_img_pt1[i + 1] - 1];// m =work[*(pnt1+1)-1];\r
+ n = label_idxtbl[label_img[pixel_index - 1] - 1];// n = label_idxtbl[label_img_pt0[i - 1] - 1];// n =work[*(pnt2-1)-1];\r
+ if (label_pixel > n) {\r
+ for (k = 0; k < wk_max; k++) {\r
+ if (label_idxtbl[k] == label_pixel) {// if( *wk == m ){\r
+ label_idxtbl[k] = n;// *wk = n;\r
+ }\r
+ }\r
+ label_pixel = n;// *pnt2 = n;\r
+ } else if (label_pixel < n) {\r
+ for (k = 0; k < wk_max; k++) {\r
+ if (label_idxtbl[k] == n) {// if( *wk == n ){\r
+ label_idxtbl[k] = label_pixel;// *wk = m;\r
+ }\r
+ }\r
+ }\r
+ work2_pt = work2[label_pixel - 1];\r
+ work2_pt[0]++;// work2[((*pnt2)-1)*7+0] ++;\r
+ work2_pt[1] += i;// work2[((*pnt2)-1)*7+1] += i;\r
+ work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j;\r
+ } else {\r
+\r
+ label_pixel = label_img[label_img_ptr1 + 1];// label_pixel = label_img_pt1[i + 1];// *pnt2 =\r
+ // *(pnt1+1);\r
+\r
+ work2_pt = work2[label_pixel - 1];\r
+ work2_pt[0]++;// work2[((*pnt2)-1)*7+0] ++;\r
+ work2_pt[1] += i;// work2[((*pnt2)-1)*7+1] += i;\r
+ work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j;\r
+ if (work2_pt[3] > i) {// if(work2[((*pnt2)-1)*7+3] > i ){\r
+ work2_pt[3] = i;// work2[((*pnt2)-1)*7+3] = i;\r
+ }\r
+ work2_pt[6] = j;// work2[((*pnt2)-1)*7+6] = j;\r
+ }\r
+ } else if ((label_img[label_img_ptr1 - 1]) > 0) {// } else if ((label_img_pt1[i - 1]) > 0) {// }else if(\r
+ // *(pnt1-1) > 0 ) {\r
+ label_pixel = label_img[label_img_ptr1 - 1];// label_pixel = label_img_pt1[i - 1];// *pnt2 =\r
+ // *(pnt1-1);\r
+\r
+ work2_pt = work2[label_pixel - 1];\r
+ work2_pt[0]++;// work2[((*pnt2)-1)*7+0] ++;\r
+ work2_pt[1] += i;// work2[((*pnt2)-1)*7+1] += i;\r
+ work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j;\r
+ if (work2_pt[4] < i) {// if( work2[((*pnt2)-1)*7+4] <i ){\r
+ work2_pt[4] = i;// work2[((*pnt2)-1)*7+4] = i;\r
+ }\r
+ work2_pt[6] = j;// work2[((*pnt2)-1)*7+6] = j;\r
+ } else if (label_img[pixel_index - 1] > 0) {// } else if (label_img_pt0[i - 1] > 0) {// }else if(*(pnt2-1) > 0) {\r
+ label_pixel = label_img[pixel_index - 1];// label_pixel = label_img_pt0[i - 1];// *pnt2 =*(pnt2-1);\r
+\r
+ work2_pt = work2[label_pixel - 1];\r
+ work2_pt[0]++;// work2[((*pnt2)-1)*7+0] ++;\r
+ work2_pt[1] += i;// work2[((*pnt2)-1)*7+1] += i;\r
+ work2_pt[2] += j;// work2[((*pnt2)-1)*7+2] += j;\r
+ if (work2_pt[4] < i) {// if( work2[((*pnt2)-1)*7+4] <i ){\r
+ work2_pt[4] = i;// work2[((*pnt2)-1)*7+4] = i;\r
+ }\r
+ } else {\r
+ // 現在地までの領域を予約\r
+ this.work_holder.reserv(wk_max);\r
+ wk_max++;\r
+ label_idxtbl[wk_max - 1] = wk_max;\r
+ label_pixel = wk_max;// work[wk_max-1] = *pnt2 = wk_max;\r
+ work2_pt = work2[wk_max - 1];\r
+ work2_pt[0] = 1;\r
+ work2_pt[1] = i;\r
+ work2_pt[2] = j;\r
+ work2_pt[3] = i;\r
+ work2_pt[4] = i;\r
+ work2_pt[5] = j;\r
+ work2_pt[6] = j;\r
+ }\r
+ label_img[pixel_index] = label_pixel;// label_img_pt0[i] = label_pixel;\r
+ }\r
+ }\r
+\r
+ }\r
+ // インデックステーブルとラベル数の計算\r
+ int wlabel_num = 1;// *label_num = *wlabel_num = j - 1;\r
+\r
+ for (i = 0; i < wk_max; i++) {// for(int i = 1; i <= wk_max; i++,wk++) {\r
+ label_idxtbl[i] = (label_idxtbl[i] == i + 1) ? wlabel_num++ : label_idxtbl[label_idxtbl[i] - 1];// *wk=(*wk==i)?j++:work[(*wk)-1];\r
+ }\r
+ wlabel_num -= 1;// *label_num = *wlabel_num = j - 1;\r
+ if (wlabel_num == 0) {// if( *label_num == 0 ) {\r
+ // 発見数0\r
+ o_destination.getLabelStack().clear();\r
+ return 0;\r
+ }\r
+ // ラベル情報の保存等\r
+ NyARLabelingLabelStack label_list = o_destination.getLabelStack();\r
+\r
+ // ラベルバッファを予約\r
+ label_list.reserv(wlabel_num);\r
+\r
+ // エリアと重心、クリップ領域を計算\r
+ NyARLabelingLabel label_pt;\r
+ NyARLabelingLabel[] labels =label_list.getArray();\r
+ for (i = 0; i < wlabel_num; i++) {\r
+ label_pt = labels[i];\r
+ label_pt.id = (short)(i + 1);\r
+ label_pt.area = 0;\r
+ label_pt.pos_x = label_pt.pos_y = 0;\r
+ label_pt.clip_l = lxsize;// wclip[i*4+0] = lxsize;\r
+ label_pt.clip_t = lysize;// wclip[i*4+2] = lysize;\r
+ label_pt.clip_r = label_pt.clip_b = 0;// wclip[i*4+3] = 0;\r
+ }\r
+\r
+ for (i = 0; i < wk_max; i++) {\r
+ label_pt = labels[label_idxtbl[i] - 1];\r
+ work2_pt = work2[i];\r
+ label_pt.area += work2_pt[0];\r
+ label_pt.pos_x += work2_pt[1];\r
+ label_pt.pos_y += work2_pt[2];\r
+ if (label_pt.clip_l > work2_pt[3]) {\r
+ label_pt.clip_l = work2_pt[3];\r
+ }\r
+ if (label_pt.clip_r < work2_pt[4]) {\r
+ label_pt.clip_r = work2_pt[4];\r
+ }\r
+ if (label_pt.clip_t > work2_pt[5]) {\r
+ label_pt.clip_t = work2_pt[5];\r
+ }\r
+ if (label_pt.clip_b < work2_pt[6]) {\r
+ label_pt.clip_b = work2_pt[6];\r
+ }\r
+ }\r
+\r
+ for (i = 0; i < wlabel_num; i++) {// for(int i = 0; i < *label_num; i++ ) {\r
+ label_pt = labels[i];\r
+ label_pt.pos_x /= label_pt.area;\r
+ label_pt.pos_y /= label_pt.area;\r
+ } \r
+ return wlabel_num;\r
+ }\r
+\r
+}\r
+\r
+/**\r
+ * NyARLabeling_O2のworkとwork2を可変長にするためのクラス\r
+ * \r
+ * \r
+ */\r
+final class NyARWorkHolder\r
+{\r
+ private final static int ARRAY_APPEND_STEP = 256;\r
+\r
+ public final int[][] work2;\r
+\r
+ private int allocate_size;\r
+\r
+ /**\r
+ * 最大i_holder_size個の動的割り当てバッファを準備する。\r
+ * \r
+ * @param i_holder_size\r
+ */\r
+ public NyARWorkHolder(int i_holder_size)\r
+ {\r
+ // ポインタだけははじめに確保しておく\r
+ this.work2 = new int[i_holder_size][];\r
+ this.allocate_size = 0;\r
+ }\r
+\r
+ /**\r
+ * i_indexで指定した番号までのバッファを準備する。\r
+ * \r
+ * @param i_index\r
+ */\r
+ public final void reserv(int i_index) throws NyARException\r
+ {\r
+ // アロケート済みなら即リターン\r
+ if (this.allocate_size > i_index) {\r
+ return;\r
+ }\r
+ // 要求されたインデクスは範囲外\r
+ if (i_index >= this.work2.length) {\r
+ throw new NyARException();\r
+ }\r
+ // 追加アロケート範囲を計算\r
+ int range = i_index + ARRAY_APPEND_STEP;\r
+ if (range >= this.work2.length) {\r
+ range = this.work2.length;\r
+ }\r
+ // アロケート\r
+ for (int i = this.allocate_size; i < range; i++) {\r
+ this.work2[i] = new int[7];\r
+ }\r
+ this.allocate_size = range;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.rlelabeling;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.stack.NyObjectStack;\r
+\r
+class RleInfoStack extends NyObjectStack<RleInfoStack.RleInfo>\r
+{\r
+ public class RleInfo\r
+ {\r
+ //継承メンバ\r
+ public int entry_x; // フラグメントラベルの位置\r
+ public int area;\r
+ public int clip_r;\r
+ public int clip_l;\r
+ public int clip_b;\r
+ public int clip_t;\r
+ public long pos_x;\r
+ public long pos_y; \r
+ } \r
+ public RleInfoStack(int i_length)\r
+ {\r
+ super(i_length, RleInfoStack.RleInfo.class);\r
+ return;\r
+ }\r
+\r
+ protected RleInfoStack.RleInfo createElement()\r
+ {\r
+ return new RleInfoStack.RleInfo();\r
+ }\r
+}\r
+/**\r
+ * [strage class]\r
+ */\r
+\r
+\r
+class RleElement\r
+{\r
+ int l;\r
+ int r;\r
+ int fid;\r
+ public static RleElement[] createArray(int i_length)\r
+ {\r
+ RleElement[] ret = new RleElement[i_length];\r
+ for (int i = 0; i < i_length; i++) {\r
+ ret[i] = new RleElement();\r
+ }\r
+ return ret;\r
+ }\r
+}\r
+\r
+\r
+// RleImageをラベリングする。\r
+public class NyARLabeling_Rle\r
+{\r
+ private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
+ private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
+ \r
+ private RleInfoStack _rlestack;\r
+ private RleElement[] _rle1;\r
+ private RleElement[] _rle2;\r
+ private int _max_area;\r
+ private int _min_area;\r
+\r
+ public NyARLabeling_Rle(int i_width,int i_height)\r
+ {\r
+ this._rlestack=new RleInfoStack(i_width*i_height*2048/(320*240)+32);\r
+ this._rle1 = RleElement.createArray(i_width/2+1);\r
+ this._rle2 = RleElement.createArray(i_width/2+1);\r
+ setAreaRange(AR_AREA_MAX,AR_AREA_MIN);\r
+\r
+ return;\r
+ }\r
+ /**\r
+ * 対象サイズ\r
+ * @param i_max\r
+ * @param i_min\r
+ */\r
+ public void setAreaRange(int i_max,int i_min)\r
+ {\r
+ this._max_area=i_max;\r
+ this._min_area=i_min;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * i_bin_bufのgsイメージをREL圧縮する。\r
+ * @param i_bin_buf\r
+ * @param i_st\r
+ * @param i_len\r
+ * @param i_out\r
+ * @param i_th\r
+ * BINラスタのときは0,GSラスタの時は閾値を指定する。\r
+ * この関数は、閾値を暗点と認識します。\r
+ * 暗点<=th<明点\r
+ * @return\r
+ */\r
+ private int toRel(int[] i_bin_buf, int i_st, int i_len, RleElement[] i_out,int i_th)\r
+ {\r
+ int current = 0;\r
+ int r = -1;\r
+ // 行確定開始\r
+ int x = i_st;\r
+ final int right_edge = i_st + i_len - 1;\r
+ while (x < right_edge) {\r
+ // 暗点(0)スキャン\r
+ if (i_bin_buf[x] > i_th) {\r
+ x++;//明点\r
+ continue;\r
+ }\r
+ // 暗点発見→暗点長を調べる\r
+ r = (x - i_st);\r
+ i_out[current].l = r;\r
+ r++;// 暗点+1\r
+ x++;\r
+ while (x < right_edge) {\r
+ if (i_bin_buf[x] > i_th) {\r
+ // 明点(1)→暗点(0)配列終了>登録\r
+ i_out[current].r = r;\r
+ current++;\r
+ x++;// 次点の確認。\r
+ r = -1;// 右端の位置を0に。\r
+ break;\r
+ } else {\r
+ // 暗点(0)長追加\r
+ r++;\r
+ x++;\r
+ }\r
+ }\r
+ }\r
+ // 最後の1点だけ判定方法が少し違うの。\r
+ if (i_bin_buf[x] > i_th) {\r
+ // 明点→rカウント中なら暗点配列終了>登録\r
+ if (r >= 0) {\r
+ i_out[current].r = r;\r
+ current++;\r
+ }\r
+ } else {\r
+ // 暗点→カウント中でなければl1で追加\r
+ if (r >= 0) {\r
+ i_out[current].r = (r + 1);\r
+ } else {\r
+ // 最後の1点の場合\r
+ i_out[current].l = (i_len - 1);\r
+ i_out[current].r = (i_len);\r
+ }\r
+ current++;\r
+ }\r
+ // 行確定\r
+ return current;\r
+ }\r
+\r
+ private void addFragment(RleElement i_rel_img, int i_nof, int i_row_index,RleInfoStack o_stack) throws NyARException\r
+ {\r
+ int l=i_rel_img.l;\r
+ final int len=i_rel_img.r - l;\r
+ i_rel_img.fid = i_nof;// REL毎の固有ID\r
+ RleInfoStack.RleInfo v = o_stack.prePush();\r
+ v.entry_x = l;\r
+ v.area =len;\r
+ v.clip_l=l;\r
+ v.clip_r=i_rel_img.r-1;\r
+ v.clip_t=i_row_index;\r
+ v.clip_b=i_row_index;\r
+ v.pos_x=(len*(2*l+(len-1)))/2;\r
+ v.pos_y=i_row_index*len;\r
+\r
+ return;\r
+ }\r
+ //所望のラスタからBIN-RLEに変換しながらの低速系も準備しようかな\r
+ \r
+ /**\r
+ * 単一閾値を使ってGSラスタをBINラスタに変換しながらラベリングします。\r
+ * @param i_gs_raster\r
+ * @param i_top\r
+ * @param i_bottom\r
+ * @param o_stack\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int labeling(NyARBinRaster i_bin_raster, int i_top, int i_bottom,RleLabelFragmentInfoStack o_stack) throws NyARException\r
+ {\r
+ return this.imple_labeling(i_bin_raster,0,i_top,i_bottom,o_stack);\r
+ }\r
+ /**\r
+ * BINラスタをラベリングします。\r
+ * @param i_gs_raster\r
+ * @param i_th\r
+ * 画像を2値化するための閾値。暗点<=th<明点となります。\r
+ * @param i_top\r
+ * @param i_bottom\r
+ * @param o_stack\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int labeling(NyARGrayscaleRaster i_gs_raster,int i_th, int i_top, int i_bottom,RleLabelFragmentInfoStack o_stack) throws NyARException\r
+ {\r
+ return this.imple_labeling(i_gs_raster,i_th,i_top,i_bottom,o_stack);\r
+ }\r
+ private int imple_labeling(INyARRaster i_raster,int i_th,int i_top, int i_bottom,RleLabelFragmentInfoStack o_stack) throws NyARException\r
+ {\r
+ // リセット処理\r
+ final RleInfoStack rlestack=this._rlestack;\r
+ rlestack.clear();\r
+\r
+ //\r
+ RleElement[] rle_prev = this._rle1;\r
+ RleElement[] rle_current = this._rle2;\r
+ int len_prev = 0;\r
+ int len_current = 0;\r
+ final int width = i_raster.getWidth();\r
+ int[] in_buf = (int[]) i_raster.getBufferReader().getBuffer();\r
+\r
+ int id_max = 0;\r
+ int label_count=0;\r
+ // 初段登録\r
+\r
+ len_prev = toRel(in_buf, i_top, width, rle_prev,i_th);\r
+ for (int i = 0; i < len_prev; i++) {\r
+ // フラグメントID=フラグメント初期値、POS=Y値、RELインデクス=行\r
+ addFragment(rle_prev[i], id_max, i_top,rlestack);\r
+ id_max++;\r
+ // nofの最大値チェック\r
+ label_count++;\r
+ }\r
+ RleInfoStack.RleInfo[] f_array = rlestack.getArray();\r
+ // 次段結合\r
+ for (int y = i_top + 1; y < i_bottom; y++) {\r
+ // カレント行の読込\r
+ len_current = toRel(in_buf, y * width, width, rle_current,i_th);\r
+ int index_prev = 0;\r
+\r
+ SCAN_CUR: for (int i = 0; i < len_current; i++) {\r
+ // index_prev,len_prevの位置を調整する\r
+ int id = -1;\r
+ // チェックすべきprevがあれば確認\r
+ SCAN_PREV: while (index_prev < len_prev) {\r
+ if (rle_current[i].l - rle_prev[index_prev].r > 0) {// 0なら8方位ラベリング\r
+ // prevがcurの左方にある→次のフラグメントを探索\r
+ index_prev++;\r
+ continue;\r
+ } else if (rle_prev[index_prev].l - rle_current[i].r > 0) {// 0なら8方位ラベリングになる\r
+ // prevがcur右方にある→独立フラグメント\r
+ addFragment(rle_current[i], id_max, y,rlestack);\r
+ id_max++;\r
+ label_count++;\r
+ // 次のindexをしらべる\r
+ continue SCAN_CUR;\r
+ }\r
+ id=rle_prev[index_prev].fid;//ルートフラグメントid\r
+ RleInfoStack.RleInfo id_ptr = f_array[id];\r
+ //結合対象(初回)->prevのIDをコピーして、ルートフラグメントの情報を更新\r
+ rle_current[i].fid = id;//フラグメントIDを保存\r
+ //\r
+ final int l= rle_current[i].l;\r
+ final int r= rle_current[i].r;\r
+ final int len=r-l;\r
+ //結合先フラグメントの情報を更新する。\r
+ id_ptr.area += len;\r
+ //tとentry_xは、結合先のを使うので更新しない。\r
+ id_ptr.clip_l=l<id_ptr.clip_l?l:id_ptr.clip_l;\r
+ id_ptr.clip_r=r>id_ptr.clip_r?r-1:id_ptr.clip_r;\r
+ id_ptr.clip_b=y;\r
+ id_ptr.pos_x+=(len*(2*l+(len-1)))/2;\r
+ id_ptr.pos_y+=y*len;\r
+ //多重結合の確認(2個目以降)\r
+ index_prev++;\r
+ while (index_prev < len_prev) {\r
+ if (rle_current[i].l - rle_prev[index_prev].r > 0) {// 0なら8方位ラベリング\r
+ // prevがcurの左方にある→prevはcurに連結していない。\r
+ break SCAN_PREV;\r
+ } else if (rle_prev[index_prev].l - rle_current[i].r > 0) {// 0なら8方位ラベリングになる\r
+ // prevがcurの右方にある→prevはcurに連結していない。\r
+ index_prev--;\r
+ continue SCAN_CUR;\r
+ }\r
+ // prevとcurは連結している→ルートフラグメントの統合\r
+ \r
+ //結合するルートフラグメントを取得\r
+ final int prev_id =rle_prev[index_prev].fid;\r
+ RleInfoStack.RleInfo prev_ptr = f_array[prev_id];\r
+ if (id != prev_id){\r
+ label_count--;\r
+ //prevとcurrentのフラグメントidを書き換える。\r
+ for(int i2=index_prev;i2<len_prev;i2++){\r
+ //prevは現在のidから最後まで\r
+ if(rle_prev[i2].fid==prev_id){\r
+ rle_prev[i2].fid=id;\r
+ }\r
+ }\r
+ for(int i2=0;i2<i;i2++){\r
+ //currentは0から現在-1まで\r
+ if(rle_current[i2].fid==prev_id){\r
+ rle_current[i2].fid=id;\r
+ }\r
+ }\r
+ \r
+ //現在のルートフラグメントに情報を集約\r
+ id_ptr.area +=prev_ptr.area;\r
+ id_ptr.pos_x+=prev_ptr.pos_x;\r
+ id_ptr.pos_y+=prev_ptr.pos_y;\r
+ //tとentry_xの決定\r
+ if (id_ptr.clip_t > prev_ptr.clip_t) {\r
+ // 現在の方が下にある。\r
+ id_ptr.clip_t = prev_ptr.clip_t;\r
+ id_ptr.entry_x = prev_ptr.entry_x;\r
+ }else if (id_ptr.clip_t < prev_ptr.clip_t) {\r
+ // 現在の方が上にある。prevにフィードバック\r
+ } else {\r
+ // 水平方向で小さい方がエントリポイント。\r
+ if (id_ptr.entry_x > prev_ptr.entry_x) {\r
+ id_ptr.entry_x = prev_ptr.entry_x;\r
+ }else{\r
+ }\r
+ }\r
+ //lの決定\r
+ if (id_ptr.clip_l > prev_ptr.clip_l) {\r
+ id_ptr.clip_l=prev_ptr.clip_l;\r
+ }else{\r
+ }\r
+ //rの決定\r
+ if (id_ptr.clip_r < prev_ptr.clip_r) {\r
+ id_ptr.clip_r=prev_ptr.clip_r;\r
+ }else{\r
+ }\r
+ //bの決定\r
+\r
+ //結合済のルートフラグメントを無効化する。\r
+ prev_ptr.area=0;\r
+ }\r
+\r
+\r
+ index_prev++;\r
+ }\r
+ index_prev--;\r
+ break;\r
+ }\r
+ // curにidが割り当てられたかを確認\r
+ // 右端独立フラグメントを追加\r
+ if (id < 0){\r
+ addFragment(rle_current[i], id_max, y,rlestack);\r
+ id_max++;\r
+ label_count++;\r
+ }\r
+ }\r
+ // prevとrelの交換\r
+ RleElement[] tmp = rle_prev;\r
+ rle_prev = rle_current;\r
+ len_prev = len_current;\r
+ rle_current = tmp;\r
+ }\r
+ //対象のラベルだけ転写\r
+ o_stack.reserv(label_count);\r
+ RleLabelFragmentInfoStack.RleLabelFragmentInfo[] o_dest_array=o_stack.getArray();\r
+ final int max=this._max_area;\r
+ final int min=this._min_area;\r
+ int active_labels=0;\r
+ for(int i=id_max-1;i>=0;i--){\r
+ final int area=f_array[i].area;\r
+ if(area<min || area>max){//対象外のエリア0のもminではじく\r
+ continue;\r
+ }\r
+ //\r
+ final RleInfoStack.RleInfo src_info=f_array[i];\r
+ final RleLabelFragmentInfoStack.RleLabelFragmentInfo dest_info=o_dest_array[active_labels];\r
+ dest_info.area=area;\r
+ dest_info.clip_b=src_info.clip_b;\r
+ dest_info.clip_r=src_info.clip_r;\r
+ dest_info.clip_t=src_info.clip_t;\r
+ dest_info.clip_l=src_info.clip_l;\r
+ dest_info.entry_x=src_info.entry_x;\r
+ dest_info.pos_x=src_info.pos_x/src_info.area;\r
+ dest_info.pos_y=src_info.pos_y/src_info.area;\r
+ active_labels++;\r
+ }\r
+ //ラベル数を再設定\r
+ o_stack.pops(label_count-active_labels);\r
+ //ラベル数を返却\r
+ return active_labels;\r
+ } \r
+}\r
+\r
+\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.labeling.rlelabeling;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelInfo;\r
+import jp.nyatla.nyartoolkit.core.labeling.NyARLabelInfoStack;\r
+\r
+\r
+public class RleLabelFragmentInfoStack extends NyARLabelInfoStack<RleLabelFragmentInfoStack.RleLabelFragmentInfo>\r
+{\r
+ public class RleLabelFragmentInfo extends NyARLabelInfo\r
+ {\r
+ //継承メンバ\r
+ //int area; // フラグメントラベルの領域数\r
+ public int entry_x; // フラグメントラベルの位置\r
+ } \r
+ public RleLabelFragmentInfoStack(int i_length)\r
+ {\r
+ super(i_length, RleLabelFragmentInfoStack.RleLabelFragmentInfo.class);\r
+ return;\r
+ }\r
+\r
+ protected RleLabelFragmentInfoStack.RleLabelFragmentInfo createElement()\r
+ {\r
+ return new RleLabelFragmentInfoStack.RleLabelFragmentInfo();\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+\r
+/**\r
+ * ARCodeとINyARColorPattの間で一致計算をするインタフェイスです。\r
+ */\r
+public interface INyARMatchPatt\r
+{\r
+ public void setARCode(NyARCode i_code);\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+\r
+/**\r
+ * INyARMatchPattのColor差分ラスタを格納するクラスです。\r
+ *\r
+ */\r
+public class NyARMatchPattDeviationBlackWhiteData\r
+{\r
+ private int _data[];\r
+ private double _pow;\r
+ //\r
+ private int _number_of_pixels;\r
+ public int[] refData()\r
+ {\r
+ return this._data;\r
+ }\r
+ public double getPow()\r
+ {\r
+ return this._pow;\r
+ }\r
+ \r
+ public NyARMatchPattDeviationBlackWhiteData(int i_width,int i_height)\r
+ {\r
+ this._number_of_pixels=i_height*i_width;\r
+ this._data=new int[this._number_of_pixels];\r
+ return;\r
+ }\r
+ /**\r
+ * XRGB[width*height]の配列から、パターンデータを構築。\r
+ * @param i_buffer\r
+ */\r
+ public void setRaster(INyARRaster i_raster)\r
+ {\r
+ //i_buffer[XRGB]→差分[BW]変換 \r
+ int i;\r
+ int ave;//<PV/>\r
+ int rgb;//<PV/>\r
+ final int[] linput=this._data;//<PV/>\r
+ final int[] buf=(int[])i_raster.getBufferReader().getBuffer();\r
+\r
+ // input配列のサイズとwhも更新// input=new int[height][width][3];\r
+ final int number_of_pixels=this._number_of_pixels;\r
+\r
+ //<平均値計算(FORの1/8展開)/>\r
+ ave = 0;\r
+ for(i=number_of_pixels-1;i>=0;i--){\r
+ rgb = buf[i];\r
+ ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);\r
+ }\r
+ ave=(number_of_pixels*255*3-ave)/(3*number_of_pixels);\r
+ //\r
+ int sum = 0,w_sum;\r
+ \r
+ //<差分値計算/>\r
+ for (i = number_of_pixels-1; i >= 0;i--) {\r
+ rgb = buf[i];\r
+ w_sum =((255*3-(rgb & 0xff)-((rgb >> 8) & 0xff)-((rgb >> 16) & 0xff))/3)-ave;\r
+ linput[i] = w_sum;\r
+ sum += w_sum * w_sum;\r
+ }\r
+ final double p=Math.sqrt((double) sum);\r
+ this._pow=p!=0.0?p:0.0000001;\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+/**\r
+ * INyARMatchPattのRGBColor差分データを格納するクラスです。\r
+ *\r
+ */\r
+public class NyARMatchPattDeviationColorData\r
+{\r
+ private int[] _data;\r
+ private double _pow;\r
+ //\r
+ private int _number_of_pixels;\r
+ private int _optimize_for_mod;\r
+ public int[] refData()\r
+ {\r
+ return this._data;\r
+ }\r
+ public double getPow()\r
+ {\r
+ return this._pow;\r
+ }\r
+ \r
+ public NyARMatchPattDeviationColorData(int i_width,int i_height)\r
+ {\r
+ this._number_of_pixels=i_height*i_width;\r
+ this._data=new int[this._number_of_pixels*3];\r
+ this._optimize_for_mod=this._number_of_pixels-(this._number_of_pixels%8); \r
+ return;\r
+ }\r
+\r
+ \r
+ /**\r
+ * NyARRasterからパターンデータをセットします。\r
+ * この関数は、データを元に所有するデータ領域を更新します。\r
+ * @param i_buffer\r
+ */\r
+ public void setRaster(INyARRaster i_raster)\r
+ {\r
+ //画素フォーマット、サイズ制限\r
+ assert i_raster.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ assert i_raster.getSize().isEqualSize(i_raster.getSize());\r
+\r
+ final int[] buf=(int[])i_raster.getBufferReader().getBuffer();\r
+ //i_buffer[XRGB]→差分[R,G,B]変換 \r
+ int i;\r
+ int ave;//<PV/>\r
+ int rgb;//<PV/>\r
+ final int[] linput=this._data;//<PV/>\r
+\r
+ // input配列のサイズとwhも更新// input=new int[height][width][3];\r
+ final int number_of_pixels=this._number_of_pixels;\r
+ final int for_mod=this._optimize_for_mod;\r
+\r
+ //<平均値計算(FORの1/8展開)>\r
+ ave = 0;\r
+ for(i=number_of_pixels-1;i>=for_mod;i--){\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);\r
+ }\r
+ for (;i>=0;) {\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;\r
+ }\r
+ //<平均値計算(FORの1/8展開)/>\r
+ ave=number_of_pixels*255*3-ave;\r
+ ave =255-(ave/ (number_of_pixels * 3));//(255-R)-ave を分解するための事前計算\r
+\r
+ int sum = 0,w_sum;\r
+ int input_ptr=number_of_pixels*3-1;\r
+ //<差分値計算(FORの1/8展開)>\r
+ for (i = number_of_pixels-1; i >= for_mod;i--) {\r
+ rgb = buf[i];\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ }\r
+ for (; i >=0;) {\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ rgb = buf[i];i--;\r
+ w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B\r
+ w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G\r
+ w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R\r
+ }\r
+ //<差分値計算(FORの1/8展開)/>\r
+ final double p=Math.sqrt((double) sum);\r
+ this._pow=p!=0.0?p:0.0000001;\r
+ return;\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+\r
+\r
+/**\r
+ * [[Strage class]]\r
+ *\r
+ */\r
+public class NyARMatchPattResult\r
+{\r
+ public static final int DIRECTION_UNKNOWN=-1;\r
+ public double confidence;\r
+ public int direction;\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+\r
+/**\r
+ * AR_TEMPLATE_MATCHING_BWと同等のルールで マーカを評価します。\r
+ * \r
+ */\r
+public class NyARMatchPatt_BlackWhite implements INyARMatchPatt\r
+{\r
+ protected NyARCode _code_patt; \r
+ protected int _pixels;\r
+ \r
+ public NyARMatchPatt_BlackWhite(int i_width, int i_height)\r
+ {\r
+ //最適化定数の計算\r
+ this._pixels=i_height*i_width;\r
+ return;\r
+ }\r
+ public NyARMatchPatt_BlackWhite(NyARCode i_code_ref)\r
+ {\r
+ //最適化定数の計算\r
+ this._pixels=i_code_ref.getWidth()*i_code_ref.getHeight();\r
+ this._code_patt=i_code_ref;\r
+ return;\r
+ } \r
+ /**\r
+ * 比較対象のARCodeをセットします。\r
+ * @throws NyARException\r
+ */\r
+ public void setARCode(NyARCode i_code_ref)\r
+ {\r
+ this._code_patt=i_code_ref;\r
+ return;\r
+ }\r
+ /**\r
+ * 現在セットされているコードとパターンを比較して、結果値o_resultを更新します。\r
+ * 比較部分はFor文を16倍展開してあります。\r
+ */\r
+ public boolean evaluate(NyARMatchPattDeviationBlackWhiteData i_patt,NyARMatchPattResult o_result) throws NyARException\r
+ {\r
+ assert this._code_patt!=null;\r
+\r
+ final int[] linput = i_patt.refData();\r
+ int sum;\r
+ double max = 0.0;\r
+ int res = NyARMatchPattResult.DIRECTION_UNKNOWN;\r
+ \r
+\r
+ for (int j = 0; j < 4; j++) {\r
+ //合計値初期化\r
+ sum=0;\r
+ final NyARMatchPattDeviationBlackWhiteData code_patt=this._code_patt.getBlackWhiteData(j);\r
+ final int[] pat_j = code_patt.refData();\r
+ //<全画素について、比較(FORの1/16展開)/>\r
+ int i;\r
+ for(i=this._pixels-1;i>=0;i--){\r
+ sum += linput[i] * pat_j[i];\r
+ }\r
+ //0.7776737688877927がでればOK\r
+ final double sum2 = sum / code_patt.getPow() / i_patt.getPow();// sum2 = sum / patpow[k][j]/ datapow;\r
+ if (sum2 > max) {\r
+ max = sum2;\r
+ res = j;\r
+ }\r
+ }\r
+ o_result.direction = res;\r
+ o_result.confidence= max;\r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+\r
+/**\r
+ * AR_TEMPLATE_MATCHING_COLORかつAR_MATCHING_WITHOUT_PCAと同等のルールで マーカーを評価します。\r
+ * \r
+ */\r
+public class NyARMatchPatt_Color_WITHOUT_PCA implements INyARMatchPatt\r
+{\r
+ protected NyARCode _code_patt;\r
+\r
+ protected int _optimize_for_mod;\r
+ protected int _rgbpixels;\r
+ public NyARMatchPatt_Color_WITHOUT_PCA(NyARCode i_code_ref)\r
+ {\r
+ int w=i_code_ref.getWidth();\r
+ int h=i_code_ref.getHeight();\r
+ //最適化定数の計算\r
+ this._rgbpixels=w*h*3;\r
+ this._optimize_for_mod=this._rgbpixels-(this._rgbpixels%16);\r
+ this.setARCode(i_code_ref);\r
+ return;\r
+ }\r
+ public NyARMatchPatt_Color_WITHOUT_PCA(int i_width, int i_height)\r
+ {\r
+ //最適化定数の計算\r
+ this._rgbpixels=i_height*i_width*3;\r
+ this._optimize_for_mod=this._rgbpixels-(this._rgbpixels%16); \r
+ return;\r
+ }\r
+ /**\r
+ * 比較対象のARCodeをセットします。\r
+ * @throws NyARException\r
+ */\r
+ public void setARCode(NyARCode i_code_ref)\r
+ {\r
+ this._code_patt=i_code_ref;\r
+ return;\r
+ }\r
+ /**\r
+ * 現在セットされているARコードとi_pattを比較します。\r
+ */\r
+ public boolean evaluate(NyARMatchPattDeviationColorData i_patt,NyARMatchPattResult o_result) throws NyARException\r
+ {\r
+ assert this._code_patt!=null;\r
+ //\r
+ final int[] linput = i_patt.refData();\r
+ int sum;\r
+ double max = Double.MIN_VALUE;\r
+ int res = NyARMatchPattResult.DIRECTION_UNKNOWN;\r
+ final int for_mod=this._optimize_for_mod;\r
+ for (int j = 0; j < 4; j++) {\r
+ //合計値初期化\r
+ sum=0;\r
+ final NyARMatchPattDeviationColorData code_patt=this._code_patt.getColorData(j);\r
+ final int[] pat_j = code_patt.refData();\r
+ //<全画素について、比較(FORの1/16展開)>\r
+ int i;\r
+ for(i=this._rgbpixels-1;i>=for_mod;i--){\r
+ sum += linput[i] * pat_j[i];\r
+ }\r
+ for (;i>=0;) {\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ sum += linput[i] * pat_j[i];i--;\r
+ }\r
+ //<全画素について、比較(FORの1/16展開)/>\r
+ final double sum2 = sum / code_patt.getPow();// sum2 = sum / patpow[k][j]/ datapow;\r
+ if (sum2 > max) {\r
+ max = sum2;\r
+ res = j;\r
+ }\r
+ }\r
+ o_result.direction = res;\r
+ o_result.confidence= max/i_patt.getPow();\r
+ return true; \r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.match;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARCode;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+\r
+/**\r
+ * AR_TEMPLATE_MATCHING_COLORかつAR_MATCHING_WITH_PCAと同等のルールで マーカーを評価します。\r
+ * \r
+ */\r
+public class NyARMatchPatt_Color_WITH_PCA extends NyARMatchPatt_Color_WITHOUT_PCA\r
+{\r
+ private final int EVEC_MAX = 10;// #define EVEC_MAX 10\r
+\r
+ private int evec_dim;// static int evec_dim;\r
+ private double[][] evec;// static double evec[EVEC_MAX][AR_PATT_SIZE_Y*AR_PATT_SIZE_X*3];\r
+ private double[][] epat = new double[4][EVEC_MAX];// static double epat[AR_PATT_NUM_MAX][4][EVEC_MAX];\r
+\r
+\r
+ public NyARMatchPatt_Color_WITH_PCA(int i_width, int i_height)\r
+ {\r
+ super(i_width,i_height);\r
+ return;\r
+ }\r
+ public NyARMatchPatt_Color_WITH_PCA(NyARCode i_code_ref)\r
+ {\r
+ super(i_code_ref);\r
+ return;\r
+ } \r
+ public boolean evaluate(NyARMatchPattDeviationColorData i_patt,NyARMatchPattResult o_result) throws NyARException\r
+ {\r
+ final int[] linput = i_patt.refData();\r
+ int sum;\r
+ double max = 0.0;\r
+ int res = NyARMatchPattResult.DIRECTION_UNKNOWN;\r
+/* \r
+ NyARException.trap(\r
+ "NyARMatchPatt_Color_WITH_PCA\n"+\r
+ "この箇所の移植は不完全です!"+\r
+ "ARToolKitの移植条件を完全に再現できていないため、evec,epatの計算が無視されています。"+\r
+ "gen_evec(void)も含めて移植の必要があるはずですが、まだ未解析です。");\r
+*/ double[] invec = new double[EVEC_MAX];\r
+ for (int i = 0; i < this.evec_dim; i++) {\r
+ invec[i] = 0.0;\r
+ for(int j=0;j<this._rgbpixels;i++){\r
+ invec[i] += this.evec[i][j] * linput[j];\r
+ }\r
+ invec[i] /= i_patt.getPow();\r
+ }\r
+ double min = 10000.0;\r
+ for (int j = 0; j < 4; j++) {\r
+ double sum2 = 0;\r
+ for (int i = 0; i < this.evec_dim; i++) {\r
+ sum2 += (invec[i] - this.epat[j][i]) * (invec[i] - this.epat[j][i]);\r
+ }\r
+ if (sum2 < min) {\r
+ min = sum2;\r
+ res = j;\r
+ // res2 = k;//kは常にインスタンスを刺すから、省略可能\r
+ }\r
+ }\r
+ sum=0;\r
+ final int[] code_data=this._code_patt.getColorData(res).refData();\r
+ for (int i = 0; i < this._rgbpixels; i++) {// for(int\r
+ sum += linput[i] * code_data[i];// sum +=input[i][i2][i3]*pat[res2][res][i][i2][i3];\r
+ }\r
+ max = sum / this._code_patt.getColorData(res).getPow() / i_patt.getPow();\r
+ o_result.direction = res;\r
+ o_result.confidence = max;\r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.param;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+\r
+public interface INyARCameraDistortionFactor\r
+{\r
+ /**\r
+ * int arParamIdeal2Observ( const double dist_factor[4], const double ix,const double iy,double *ox, double *oy ) 関数の代替関数\r
+ * \r
+ * @param i_in\r
+ * @param o_out\r
+ */\r
+ public void ideal2Observ(final NyARDoublePoint2d i_in, NyARDoublePoint2d o_out);\r
+ /**\r
+ * ideal2Observをまとめて実行します。\r
+ * @param i_in\r
+ * @param o_out\r
+ */\r
+ public void ideal2ObservBatch(final NyARDoublePoint2d[] i_in, NyARDoublePoint2d[] o_out, int i_size);\r
+ /**\r
+ * int arParamObserv2Ideal( const double dist_factor[4], const double ox,const double oy,double *ix, double *iy );\r
+ * \r
+ * @param ix\r
+ * @param iy\r
+ * @param ix\r
+ * @param iy\r
+ * @return\r
+ */\r
+ public void observ2Ideal(double ix, double iy, NyARDoublePoint2d o_point);\r
+ /**\r
+ * 指定範囲のobserv2Idealをまとめて実行して、結果をo_idealに格納します。\r
+ * @param i_x_coord\r
+ * @param i_y_coord\r
+ * @param i_start\r
+ * coord開始点\r
+ * @param i_num\r
+ * 計算数\r
+ * @param o_ideal\r
+ * 出力バッファ[i_num][2]であること。\r
+ */\r
+ public void observ2IdealBatch(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, double[] o_x_coord,double[] o_y_coord);\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.param;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+\r
+/**\r
+ * カメラの歪み成分を格納するクラスと、補正関数群\r
+ * http://www.hitl.washington.edu/artoolkit/Papers/ART02-Tutorial.pdf\r
+ * 11ページを読むといいよ。\r
+ * \r
+ * x=x(xi-x0),y=s(yi-y0)\r
+ * d^2=x^2+y^2\r
+ * p=(1-fd^2)\r
+ * xd=px+x0,yd=py+y0\r
+ */\r
+public class NyARCameraDistortionFactor implements INyARCameraDistortionFactor\r
+{\r
+ private static final int PD_LOOP = 3;\r
+ private double _f0;//x0\r
+ private double _f1;//y0\r
+ private double _f2;//100000000.0*f\r
+ private double _f3;//s\r
+ public void copyFrom(NyARCameraDistortionFactor i_ref)\r
+ {\r
+ this._f0=i_ref._f0;\r
+ this._f1=i_ref._f1;\r
+ this._f2=i_ref._f2;\r
+ this._f3=i_ref._f3;\r
+ return;\r
+ }\r
+ /**\r
+ * 配列の値をファクタ値としてセットする。\r
+ * @param i_factor\r
+ * 4要素以上の配列\r
+ */\r
+ public void setValue(double[] i_factor)\r
+ {\r
+ this._f0=i_factor[0];\r
+ this._f1=i_factor[1];\r
+ this._f2=i_factor[2];\r
+ this._f3=i_factor[3];\r
+ return;\r
+ }\r
+ public void getValue(double[] o_factor)\r
+ {\r
+ o_factor[0]=this._f0;\r
+ o_factor[1]=this._f1;\r
+ o_factor[2]=this._f2;\r
+ o_factor[3]=this._f3;\r
+ return;\r
+ } \r
+ public void changeScale(double i_scale)\r
+ {\r
+ this._f0=this._f0*i_scale;// newparam->dist_factor[0] =source->dist_factor[0] *scale;\r
+ this._f1=this._f1*i_scale;// newparam->dist_factor[1] =source->dist_factor[1] *scale;\r
+ this._f2=this._f2/ (i_scale * i_scale);// newparam->dist_factor[2]=source->dist_factor[2]/ (scale*scale);\r
+ //this.f3=this.f3;// newparam->dist_factor[3] =source->dist_factor[3];\r
+ return;\r
+ }\r
+ /**\r
+ * int arParamIdeal2Observ( const double dist_factor[4], const double ix,const double iy,double *ox, double *oy ) 関数の代替関数\r
+ * \r
+ * @param i_in\r
+ * @param o_out\r
+ */\r
+ public void ideal2Observ(final NyARDoublePoint2d i_in, NyARDoublePoint2d o_out)\r
+ {\r
+ final double x = (i_in.x - this._f0) * this._f3;\r
+ final double y = (i_in.y - this._f1) * this._f3;\r
+ if (x == 0.0 && y == 0.0) {\r
+ o_out.x = this._f0;\r
+ o_out.y = this._f1;\r
+ } else {\r
+ final double d = 1.0 - this._f2 / 100000000.0 * (x * x + y * y);\r
+ o_out.x = x * d + this._f0;\r
+ o_out.y = y * d + this._f1;\r
+ }\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * ideal2Observをまとめて実行します。\r
+ * @param i_in\r
+ * @param o_out\r
+ */\r
+ public void ideal2ObservBatch(final NyARDoublePoint2d[] i_in, NyARDoublePoint2d[] o_out, int i_size)\r
+ {\r
+ double x, y;\r
+ final double d0 = this._f0;\r
+ final double d1 = this._f1;\r
+ final double d3 = this._f3;\r
+ final double d2_w = this._f2 / 100000000.0;\r
+ for (int i = 0; i < i_size; i++) {\r
+ x = (i_in[i].x - d0) * d3;\r
+ y = (i_in[i].y - d1) * d3;\r
+ if (x == 0.0 && y == 0.0) {\r
+ o_out[i].x = d0;\r
+ o_out[i].y = d1;\r
+ } else {\r
+ final double d = 1.0 - d2_w * (x * x + y * y);\r
+ o_out[i].x = x * d + d0;\r
+ o_out[i].y = y * d + d1;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * int arParamObserv2Ideal( const double dist_factor[4], const double ox,const double oy,double *ix, double *iy );\r
+ * \r
+ * @param ix\r
+ * @param iy\r
+ * @param ix\r
+ * @param iy\r
+ * @return\r
+ */\r
+ public void observ2Ideal(double ix, double iy, NyARDoublePoint2d o_point)\r
+ {\r
+ double z02, z0, p, q, z, px, py, opttmp_1;\r
+ final double d0 = this._f0;\r
+ final double d1 = this._f1;\r
+\r
+ px = ix - d0;\r
+ py = iy - d1;\r
+ p = this._f2 / 100000000.0;\r
+ z02 = px * px + py * py;\r
+ q = z0 = Math.sqrt(z02);// Optimize//q = z0 = Math.sqrt(px*px+ py*py);\r
+\r
+ for (int i = 1;; i++) {\r
+ if (z0 != 0.0) {\r
+ // Optimize opttmp_1\r
+ opttmp_1 = p * z02;\r
+ z = z0 - ((1.0 - opttmp_1) * z0 - q) / (1.0 - 3.0 * opttmp_1);\r
+ px = px * z / z0;\r
+ py = py * z / z0;\r
+ } else {\r
+ px = 0.0;\r
+ py = 0.0;\r
+ break;\r
+ }\r
+ if (i == PD_LOOP) {\r
+ break;\r
+ }\r
+ z02 = px * px + py * py;\r
+ z0 = Math.sqrt(z02);// Optimize//z0 = Math.sqrt(px*px+ py*py);\r
+ }\r
+ o_point.x = px / this._f3 + d0;\r
+ o_point.y = py / this._f3 + d1;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 指定範囲のobserv2Idealをまとめて実行して、結果をo_idealに格納します。\r
+ * @param i_x_coord\r
+ * @param i_y_coord\r
+ * @param i_start\r
+ * coord開始点\r
+ * @param i_num\r
+ * 計算数\r
+ * @param o_ideal\r
+ * 出力バッファ[i_num][2]であること。\r
+ */\r
+ public void observ2IdealBatch(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, double[] o_x_coord,double[] o_y_coord)\r
+ {\r
+ double z02, z0, q, z, px, py, opttmp_1;\r
+ final double d0 = this._f0;\r
+ final double d1 = this._f1;\r
+ final double d3 = this._f3;\r
+ final double p = this._f2 / 100000000.0;\r
+ for (int j = 0; j < i_num; j++) {\r
+\r
+ px = i_x_coord[i_start + j] - d0;\r
+ py = i_y_coord[i_start + j] - d1;\r
+\r
+ z02 = px * px + py * py;\r
+ q = z0 = Math.sqrt(z02);// Optimize//q = z0 = Math.sqrt(px*px+py*py);\r
+\r
+ for (int i = 1;; i++) {\r
+ if (z0 != 0.0) {\r
+ // Optimize opttmp_1\r
+ opttmp_1 = p * z02;\r
+ z = z0 - ((1.0 - opttmp_1) * z0 - q)/ (1.0 - 3.0 * opttmp_1);\r
+ px = px * z / z0;\r
+ py = py * z / z0;\r
+ } else {\r
+ px = 0.0;\r
+ py = 0.0;\r
+ break;\r
+ }\r
+ if (i == PD_LOOP) {\r
+ break;\r
+ }\r
+ z02 = px * px + py * py;\r
+ z0 = Math.sqrt(z02);// Optimize//z0 = Math.sqrt(px*px+ py*py);\r
+ }\r
+ o_x_coord[j] = px / d3 + d0;\r
+ o_y_coord[j] = py / d3 + d1;\r
+ }\r
+ return;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.param;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 歪み矯正した座標系を格納したクラスです。\r
+ * 2次元ラスタを1次元配列で表現します。\r
+ *\r
+ */\r
+public class NyARObserv2IdealMap\r
+{\r
+ protected int _stride;\r
+ protected double[] _mapx;\r
+ protected double[] _mapy;\r
+ public NyARObserv2IdealMap(NyARCameraDistortionFactor i_distfactor,NyARIntSize i_screen_size)\r
+ {\r
+ NyARDoublePoint2d opoint=new NyARDoublePoint2d();\r
+ this._mapx=new double[i_screen_size.w*i_screen_size.h];\r
+ this._mapy=new double[i_screen_size.w*i_screen_size.h];\r
+ this._stride=i_screen_size.w;\r
+ int ptr=i_screen_size.h*i_screen_size.w-1;\r
+ //歪みマップを構築\r
+ for(int i=i_screen_size.h-1;i>=0;i--)\r
+ {\r
+ for(int i2=i_screen_size.w-1;i2>=0;i2--)\r
+ {\r
+ i_distfactor.observ2Ideal(i2,i, opoint);\r
+ this._mapx[ptr]=opoint.x;\r
+ this._mapy[ptr]=opoint.y;\r
+ ptr--;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ public void observ2Ideal(int ix, int iy, NyARDoublePoint2d o_point)\r
+ {\r
+ int idx=ix+iy*this._stride;\r
+ o_point.x=this._mapx[idx];\r
+ o_point.y=this._mapy[idx];\r
+ return;\r
+ }\r
+ public void observ2IdealBatch(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num, double[] o_x_coord,double[] o_y_coord,int i_out_start_index)\r
+ {\r
+ int idx;\r
+ int ptr=i_out_start_index;\r
+ final double[] mapx=this._mapx;\r
+ final double[] mapy=this._mapy;\r
+ final int stride=this._stride;\r
+ for (int j = 0; j < i_num; j++){\r
+ idx=i_x_coord[i_start + j]+i_y_coord[i_start + j]*stride;\r
+ o_x_coord[ptr]=mapx[idx];\r
+ o_y_coord[ptr]=mapy[idx];\r
+ ptr++;\r
+ }\r
+ return;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.param;\r
+\r
+import java.io.*;\r
+import java.nio.*;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * typedef struct { int xsize, ysize; double mat[3][4]; double dist_factor[4]; } ARParam;\r
+ * NyARの動作パラメータを格納するクラス\r
+ *\r
+ */\r
+public class NyARParam\r
+{\r
+ protected NyARIntSize _screen_size=new NyARIntSize();\r
+ private static final int SIZE_OF_PARAM_SET = 4 + 4 + (3 * 4 * 8) + (4 * 8);\r
+ private NyARCameraDistortionFactor _dist=new NyARCameraDistortionFactor();\r
+ private NyARPerspectiveProjectionMatrix _projection_matrix=new NyARPerspectiveProjectionMatrix();\r
+\r
+ public NyARIntSize getScreenSize()\r
+ {\r
+ return this._screen_size;\r
+ }\r
+\r
+ public NyARPerspectiveProjectionMatrix getPerspectiveProjectionMatrix()\r
+ {\r
+ return this._projection_matrix;\r
+ }\r
+ public NyARCameraDistortionFactor getDistortionFactor()\r
+ {\r
+ return this._dist;\r
+ }\r
+ /**\r
+ * \r
+ * @param i_factor\r
+ * NyARCameraDistortionFactorにセットする配列を指定する。要素数は4であること。\r
+ * @param i_projection\r
+ * NyARPerspectiveProjectionMatrixセットする配列を指定する。要素数は12であること。\r
+ */\r
+ public void setValue(double[] i_factor,double[] i_projection)\r
+ {\r
+ this._dist.setValue(i_factor);\r
+ this._projection_matrix.setValue(i_projection);\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * ARToolKit標準ファイルから1個目の設定をロードする。\r
+ * \r
+ * @param i_filename\r
+ * @throws NyARException\r
+ */\r
+ public void loadARParamFromFile(String i_filename) throws NyARException\r
+ {\r
+ try {\r
+ loadARParam(new FileInputStream(i_filename));\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * int arParamChangeSize( ARParam *source, int xsize, int ysize, ARParam *newparam );\r
+ * 関数の代替関数 サイズプロパティをi_xsize,i_ysizeに変更します。\r
+ * @param i_xsize\r
+ * @param i_ysize\r
+ * @param newparam\r
+ * @return\r
+ * \r
+ */\r
+ public void changeScreenSize(int i_xsize, int i_ysize)\r
+ {\r
+ final double scale = (double) i_xsize / (double) (this._screen_size.w);// scale = (double)xsize / (double)(source->xsize);\r
+ //スケールを変更\r
+ this._dist.changeScale(scale);\r
+ this._projection_matrix.changeScale(scale);\r
+ this._screen_size.w = i_xsize;// newparam->xsize = xsize;\r
+ this._screen_size.h = i_ysize;// newparam->ysize = ysize;\r
+ return;\r
+ }\r
+\r
+\r
+ /**\r
+ * int arParamLoad( const char *filename, int num, ARParam *param, ...);\r
+ * i_streamの入力ストリームからi_num個の設定を読み込み、パラメタを配列にして返します。\r
+ * \r
+ * @param i_stream\r
+ * @throws Exception\r
+ */\r
+ public void loadARParam(InputStream i_stream)throws NyARException\r
+ {\r
+ try {\r
+ byte[] buf = new byte[SIZE_OF_PARAM_SET];\r
+ i_stream.read(buf);\r
+ double[] tmp=new double[12];\r
+\r
+ // バッファを加工\r
+ ByteBuffer bb = ByteBuffer.wrap(buf);\r
+ bb.order(ByteOrder.BIG_ENDIAN);\r
+ this._screen_size.w = bb.getInt();\r
+ this._screen_size.h = bb.getInt();\r
+ //double値を12個読み込む\r
+ for(int i=0;i<12;i++){\r
+ tmp[i]=bb.getDouble();\r
+ }\r
+ //Projectionオブジェクトにセット\r
+ this._projection_matrix.setValue(tmp);\r
+ //double値を4個読み込む\r
+ for (int i = 0; i < 4; i++) {\r
+ tmp[i]=bb.getDouble();\r
+ }\r
+ //Factorオブジェクトにセット\r
+ this._dist.setValue(tmp);\r
+ } catch (Exception e) {\r
+ throw new NyARException(e);\r
+ }\r
+ return;\r
+ }\r
+\r
+ public void saveARParam(OutputStream i_stream)throws Exception\r
+ {\r
+ NyARException.trap("未チェックの関数");\r
+ byte[] buf = new byte[SIZE_OF_PARAM_SET];\r
+ // バッファをラップ\r
+ ByteBuffer bb = ByteBuffer.wrap(buf);\r
+ bb.order(ByteOrder.BIG_ENDIAN);\r
+\r
+ // 書き込み\r
+ bb.putInt(this._screen_size.w);\r
+ bb.putInt(this._screen_size.h);\r
+ double[] tmp=new double[12];\r
+ //Projectionを読み出し\r
+ this._projection_matrix.getValue(tmp);\r
+ //double値を12個書き込む\r
+ for(int i=0;i<12;i++){\r
+ tmp[i]=bb.getDouble();\r
+ }\r
+ //Factorを読み出し\r
+ this._dist.getValue(tmp);\r
+ //double値を4個書き込む\r
+ for (int i = 0; i < 4; i++) {\r
+ tmp[i]=bb.getDouble();\r
+ }\r
+ i_stream.write(buf);\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.param;\r
+\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix34;\r
+\r
+/**\r
+ * 透視変換行列を格納します。\r
+ * http://www.hitl.washington.edu/artoolkit/Papers/ART02-Tutorial.pdf\r
+ * 7ページを見るといいよ。\r
+ *\r
+ */\r
+final public class NyARPerspectiveProjectionMatrix extends NyARDoubleMatrix34\r
+{\r
+ /*\r
+ * static double dot( double a1, double a2, double a3,double b1, double b2,double b3 )\r
+ */\r
+ private final static double dot(double a1, double a2, double a3, double b1,double b2, double b3)\r
+ {\r
+ return (a1 * b1 + a2 * b2 + a3 * b3);\r
+ }\r
+\r
+ /* static double norm( double a, double b, double c ) */\r
+ private final static double norm(double a, double b, double c)\r
+ {\r
+ return Math.sqrt(a * a + b * b + c * c);\r
+ }\r
+\r
+ /**\r
+ * int arParamDecompMat( double source[3][4], double cpara[3][4], double trans[3][4] ); 関数の置き換え Optimize STEP[754->665]\r
+ * \r
+ * @param o_cpara\r
+ * 戻り引数。3x4のマトリクスを指定すること。\r
+ * @param o_trans\r
+ * 戻り引数。3x4のマトリクスを指定すること。\r
+ * @return\r
+ */\r
+ public void decompMat(NyARMat o_cpara, NyARMat o_trans)\r
+ {\r
+ double rem1, rem2, rem3;\r
+ double c00,c01,c02,c03,c10,c11,c12,c13,c20,c21,c22,c23;\r
+ if (this.m23>= 0) {// if( source[2][3] >= 0 ) {\r
+ // <Optimize>\r
+ // for(int r = 0; r < 3; r++ ){\r
+ // for(int c = 0; c < 4; c++ ){\r
+ // Cpara[r][c]=source[r][c];//Cpara[r][c] = source[r][c];\r
+ // }\r
+ // }\r
+ c00=this.m00;\r
+ c01=this.m01;\r
+ c02=this.m02;\r
+ c03=this.m03;\r
+ c10=this.m10;\r
+ c11=this.m11;\r
+ c12=this.m12;\r
+ c13=this.m13;\r
+ c20=this.m20;\r
+ c21=this.m21;\r
+ c22=this.m22;\r
+ c23=this.m23;\r
+ } else {\r
+ // <Optimize>\r
+ // for(int r = 0; r < 3; r++ ){\r
+ // for(int c = 0; c < 4; c++ ){\r
+ // Cpara[r][c]=-source[r][c];//Cpara[r][c] = -(source[r][c]);\r
+ // }\r
+ // }\r
+ c00=-this.m00;\r
+ c01=-this.m01;\r
+ c02=-this.m02;\r
+ c03=-this.m03;\r
+ c10=-this.m10;\r
+ c11=-this.m11;\r
+ c12=-this.m12;\r
+ c13=-this.m13;\r
+ c20=-this.m20;\r
+ c21=-this.m21;\r
+ c22=-this.m22;\r
+ c23=-this.m23;\r
+ }\r
+\r
+ double[][] cpara = o_cpara.getArray();\r
+ double[][] trans = o_trans.getArray();\r
+ for (int r = 0; r < 3; r++) {\r
+ for (int c = 0; c < 4; c++) {\r
+ cpara[r][c] = 0.0;// cpara[r][c] = 0.0;\r
+ }\r
+ }\r
+ cpara[2][2] = norm(c20, c21, c22);// cpara[2][2] =norm( Cpara[2][0],Cpara[2][1],Cpara[2][2]);\r
+ trans[2][0] = c20 / cpara[2][2];// trans[2][0] = Cpara[2][0] /cpara[2][2];\r
+ trans[2][1] = c21 / cpara[2][2];// trans[2][1] = Cpara[2][1] / cpara[2][2];\r
+ trans[2][2] = c22 / cpara[2][2];// trans[2][2] =Cpara[2][2] /cpara[2][2];\r
+ trans[2][3] = c23 / cpara[2][2];// trans[2][3] =Cpara[2][3] /cpara[2][2];\r
+\r
+ cpara[1][2] = dot(trans[2][0], trans[2][1], trans[2][2], c10, c11, c12);// cpara[1][2]=dot(trans[2][0],trans[2][1],trans[2][2],Cpara[1][0],Cpara[1][1],Cpara[1][2]);\r
+ rem1 = c10 - cpara[1][2] * trans[2][0];// rem1 =Cpara[1][0] -cpara[1][2] *trans[2][0];\r
+ rem2 = c11 - cpara[1][2] * trans[2][1];// rem2 =Cpara[1][1] -cpara[1][2] *trans[2][1];\r
+ rem3 = c12 - cpara[1][2] * trans[2][2];// rem3 =Cpara[1][2] -cpara[1][2] *trans[2][2];\r
+ cpara[1][1] = norm(rem1, rem2, rem3);// cpara[1][1] = norm( rem1,// rem2, rem3 );\r
+ trans[1][0] = rem1 / cpara[1][1];// trans[1][0] = rem1 / cpara[1][1];\r
+ trans[1][1] = rem2 / cpara[1][1];// trans[1][1] = rem2 / cpara[1][1];\r
+ trans[1][2] = rem3 / cpara[1][1];// trans[1][2] = rem3 / cpara[1][1];\r
+\r
+ cpara[0][2] = dot(trans[2][0], trans[2][1], trans[2][2], c00, c01, c02);// cpara[0][2] =dot(trans[2][0], trans[2][1],trans[2][2],Cpara[0][0],Cpara[0][1],Cpara[0][2]);\r
+ cpara[0][1] = dot(trans[1][0], trans[1][1], trans[1][2], c00, c01, c02);// cpara[0][1]=dot(trans[1][0],trans[1][1],trans[1][2],Cpara[0][0],Cpara[0][1],Cpara[0][2]);\r
+ rem1 = c00 - cpara[0][1] * trans[1][0] - cpara[0][2]* trans[2][0];// rem1 = Cpara[0][0] - cpara[0][1]*trans[1][0]- cpara[0][2]*trans[2][0];\r
+ rem2 = c01 - cpara[0][1] * trans[1][1] - cpara[0][2]* trans[2][1];// rem2 = Cpara[0][1] - cpara[0][1]*trans[1][1]- cpara[0][2]*trans[2][1];\r
+ rem3 = c02 - cpara[0][1] * trans[1][2] - cpara[0][2]* trans[2][2];// rem3 = Cpara[0][2] - cpara[0][1]*trans[1][2] - cpara[0][2]*trans[2][2];\r
+ cpara[0][0] = norm(rem1, rem2, rem3);// cpara[0][0] = norm( rem1,rem2, rem3 );\r
+ trans[0][0] = rem1 / cpara[0][0];// trans[0][0] = rem1 / cpara[0][0];\r
+ trans[0][1] = rem2 / cpara[0][0];// trans[0][1] = rem2 / cpara[0][0];\r
+ trans[0][2] = rem3 / cpara[0][0];// trans[0][2] = rem3 / cpara[0][0];\r
+\r
+ trans[1][3] = (c13 - cpara[1][2] * trans[2][3])/ cpara[1][1];// trans[1][3] = (Cpara[1][3] -cpara[1][2]*trans[2][3]) / cpara[1][1];\r
+ trans[0][3] = (c03 - cpara[0][1] * trans[1][3] - cpara[0][2]* trans[2][3])/ cpara[0][0];// trans[0][3] = (Cpara[0][3] -cpara[0][1]*trans[1][3]-cpara[0][2]*trans[2][3]) / cpara[0][0];\r
+\r
+ for (int r = 0; r < 3; r++) {\r
+ for (int c = 0; c < 3; c++) {\r
+ cpara[r][c] /= cpara[2][2];// cpara[r][c] /= cpara[2][2];\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * int arParamChangeSize( ARParam *source, int xsize, int ysize, ARParam *newparam );\r
+ * Matrixのスケールを変換します。\r
+ * @param i_scale\r
+ * \r
+ */\r
+ public void changeScale(double i_scale)\r
+ {\r
+ this.m00=this.m00*i_scale;\r
+ this.m10=this.m10*i_scale;\r
+ this.m01=this.m01*i_scale;\r
+ this.m11=this.m11*i_scale;\r
+ this.m02=this.m02*i_scale;\r
+ this.m12=this.m12*i_scale;\r
+ this.m03=this.m03*i_scale;\r
+ this.m13=this.m13*i_scale;\r
+ //for (int i = 0; i < 4; i++) {\r
+ // array34[0 * 4 + i] = array34[0 * 4 + i] * scale;// newparam->mat[0][i]=source->mat[0][i]* scale;\r
+ // array34[1 * 4 + i] = array34[1 * 4 + i] * scale;// newparam->mat[1][i]=source->mat[1][i]* scale;\r
+ // array34[2 * 4 + i] = array34[2 * 4 + i];// newparam->mat[2][i] = source->mat[2][i];\r
+ //}\r
+ return;\r
+ }\r
+\r
+ \r
+ \r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pca2d;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+\r
+public interface INyARPca2d\r
+{\r
+ /**\r
+ * 通常のPCA\r
+ * @param i_v1\r
+ * @param i_v2\r
+ * @param i_start\r
+ * @param i_number_of_point\r
+ * @param o_evec\r
+ * 要素2の変数を指定してください。\r
+ * @param o_ev\r
+ * 要素2の変数を指定してください。\r
+ * @param o_mean\r
+ * @throws NyARException\r
+ */\r
+ public void pca(double[] i_v1,double[] i_v2,int i_number_of_point,NyARDoubleMatrix22 o_evec, double[] o_ev,double[] o_mean) throws NyARException;\r
+ /**\r
+ * カメラ歪み補正つきのPCA\r
+ * @param i_x\r
+ * @param i_y\r
+ * @param i_start\r
+ * @param i_number_of_point\r
+ * @param i_factor\r
+ * @param o_evec\r
+ * @param o_mean\r
+ * @throws NyARException\r
+ */\r
+// public void pcaWithDistortionFactor(int[] i_x,int[] i_y,int i_start,int i_number_of_point,INyARCameraDistortionFactor i_factor,NyARDoubleMatrix22 o_evec,NyARDoublePoint2d o_ev, NyARDoublePoint2d o_mean) throws NyARException;\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pca2d;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.NyARVec;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+/**\r
+ * NyARMatrixを利用した主成分分析\r
+ * ARToolKitと同じ処理をします。\r
+ */\r
+public class NyARPca2d_MatrixPCA implements INyARPca2d\r
+{\r
+ private final NyARMat __pca_input = new NyARMat(1, 2);\r
+ private final NyARMat __pca_evec = new NyARMat(2, 2);\r
+ private final NyARVec __pca_ev = new NyARVec(2);\r
+ private final NyARVec __pca_mean = new NyARVec(2); \r
+ \r
+ public void pca(double[] i_v1,double[] i_v2,int i_number_of_point,NyARDoubleMatrix22 o_evec, double[] o_ev,double[] o_mean) throws NyARException\r
+ {\r
+ final NyARMat input = this.__pca_input;// 次処理で初期化される。 \r
+ // pcaの準備\r
+ input.realloc(i_number_of_point, 2);\r
+ final double[][] input_array=input.getArray();\r
+ for(int i=0;i<i_number_of_point;i++){\r
+ input_array[i][0]=i_v1[i];\r
+ input_array[i][1]=i_v2[i];\r
+ }\r
+ // 主成分分析\r
+ input.pca(this.__pca_evec, this.__pca_ev, this.__pca_mean);\r
+ final double[] mean_array = this.__pca_mean.getArray();\r
+ final double[][] evec_array = this.__pca_evec.getArray();\r
+ final double[] ev_array=this.__pca_ev.getArray();\r
+ o_evec.m00=evec_array[0][0];\r
+ o_evec.m01=evec_array[0][1];\r
+ o_evec.m10=evec_array[1][0];\r
+ o_evec.m11=evec_array[1][1];\r
+ o_ev[0]=ev_array[0];\r
+ o_ev[1]=ev_array[1];\r
+ o_mean[0]=mean_array[0];\r
+ o_mean[1]=mean_array[1];\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pca2d;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+\r
+/**\r
+ * ARToolkitのPCA関数を二次元に特化させて単純化したもの\r
+ *\r
+ */\r
+public class NyARPca2d_MatrixPCA_O2 implements INyARPca2d\r
+{\r
+ private static final double PCA_EPS = 1e-6; // #define EPS 1e-6\r
+\r
+ private static final int PCA_MAX_ITER = 100; // #define MAX_ITER 100\r
+\r
+ private static final double PCA_VZERO = 1e-16; // #define VZERO 1e-16\r
+\r
+ /**\r
+ * static int QRM( ARMat *a, ARVec *dv )の代替関数\r
+ * \r
+ * @param a\r
+ * @param dv\r
+ * @throws NyARException\r
+ */\r
+ private static void PCA_QRM(NyARDoubleMatrix22 o_matrix, double[] dv) throws NyARException\r
+ {\r
+ double w, t, s, x, y, c;\r
+ double ev1;\r
+ double dv_x,dv_y;\r
+ double mat00,mat01,mat10,mat11;\r
+ // <this.vecTridiagonalize2d(i_mat, dv, ev);>\r
+ dv_x = o_matrix.m00;// this.m[dim - 2][dim - 2];// d.v[dim-2]=a.m[dim-2][dim-2];//d->v[dim-2]=a->m[(dim-2)*dim+(dim-2)];\r
+ ev1 = o_matrix.m01;// this.m[dim - 2][dim - 1];// e.v[dim-2+i_e_start]=a.m[dim-2][dim-1];//e->v[dim-2] = a->m[(dim-2)*dim+(dim-1)];\r
+ dv_y = o_matrix.m11;// this.m[dim - 1][dim - 1];// d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] =a->m[(dim-1)*dim+(dim-1)];\r
+ // 単位行列にする。\r
+ mat00 = mat11 = 1;\r
+ mat01 = mat10 = 0;\r
+ // </this.vecTridiagonalize2d(i_mat, dv, ev);>\r
+\r
+ // int j = 1;\r
+ // // while(j>0 && fabs(ev->v[j])>EPS*(fabs(dv->v[j-1])+fabs(dv->v[j])))\r
+ // while (j > 0 && Math.abs(ev1) > PCA_EPS * (Math.abs(dv.x) + Math.abs(dv.y))) {\r
+ // j--;\r
+ // }\r
+ // if (j == 0) {\r
+ int iter = 0;\r
+ do {\r
+ iter++;\r
+ if (iter > PCA_MAX_ITER) {\r
+ break;\r
+ }\r
+ w = (dv_x - dv_y) / 2;// w = (dv->v[h-1] -dv->v[h]) / 2;//ここ?\r
+ t = ev1 * ev1;// t = ev->v[h] * ev->v[h];\r
+ s = Math.sqrt(w * w + t);\r
+ if (w < 0) {\r
+ s = -s;\r
+ }\r
+ x = dv_x - dv_y + t / (w + s);// x = dv->v[j] -dv->v[h] +t/(w+s);\r
+ y = ev1;// y = ev->v[j+1];\r
+\r
+ if (Math.abs(x) >= Math.abs(y)) {\r
+ if (Math.abs(x) > PCA_VZERO) {\r
+ t = -y / x;\r
+ c = 1 / Math.sqrt(t * t + 1);\r
+ s = t * c;\r
+ } else {\r
+ c = 1.0;\r
+ s = 0.0;\r
+ }\r
+ } else {\r
+ t = -x / y;\r
+ s = 1.0 / Math.sqrt(t * t + 1);\r
+ c = t * s;\r
+ }\r
+ w = dv_x - dv_y;// w = dv->v[k] -dv->v[k+1];\r
+ t = (w * s + 2 * c * ev1) * s;// t = (w * s +2 * c *ev->v[k+1]) *s;\r
+ dv_x -= t;// dv->v[k] -= t;\r
+ dv_y += t;// dv->v[k+1] += t;\r
+ ev1 += s * (c * w - 2 * s * ev1);// ev->v[k+1]+= s * (c* w- 2* s *ev->v[k+1]);\r
+\r
+ x = mat00;// x = a->m[k*dim+i];\r
+ y = mat10;// y = a->m[(k+1)*dim+i];\r
+ mat00 = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;\r
+ mat10 = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;\r
+ \r
+ x = mat01;// x = a->m[k*dim+i];\r
+ y = mat11;// y = a->m[(k+1)*dim+i];\r
+ mat01 = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;\r
+ mat11 = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;\r
+ } while (Math.abs(ev1) > PCA_EPS * (Math.abs(dv_x) + Math.abs(dv_y)));\r
+ // }\r
+\r
+ t = dv_x;// t = dv->v[h];\r
+ if (dv_y > t) {// if( dv->v[i] > t ) {\r
+ t = dv_y;// t = dv->v[h];\r
+ dv_y = dv_x;// dv->v[h] = dv->v[k];\r
+ dv_x = t;// dv->v[k] = t;\r
+ // 行の入れ替え\r
+ o_matrix.m00 = mat10;\r
+ o_matrix.m01 = mat11;\r
+ o_matrix.m10 = mat00; \r
+ o_matrix.m11 = mat01;\r
+ \r
+ } else {\r
+ // 行の入れ替えはなし\r
+ o_matrix.m00 = mat00;\r
+ o_matrix.m01 = mat01;\r
+ o_matrix.m10 = mat10; \r
+ o_matrix.m11 = mat11;\r
+ }\r
+ dv[0]=dv_x;\r
+ dv[1]=dv_y;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * static int PCA( ARMat *input, ARMat *output, ARVec *ev )\r
+ * \r
+ * @param output\r
+ * @param o_ev\r
+ * @throws NyARException\r
+ */\r
+ private void PCA_PCA(double[] i_v1,double[] i_v2,int i_number_of_data,NyARDoubleMatrix22 o_matrix, double[] o_ev,double[] o_mean) throws NyARException\r
+ {\r
+ // double[] mean_array=mean.getArray();\r
+ // mean.zeroClear();\r
+\r
+ //PCA_EXの処理\r
+ double sx = 0;\r
+ double sy = 0;\r
+ for (int i = 0; i < i_number_of_data; i++) {\r
+ sx += i_v1[i];\r
+ sy += i_v2[i];\r
+ }\r
+ sx = sx / i_number_of_data;\r
+ sy = sy / i_number_of_data;\r
+ \r
+ //PCA_CENTERとPCA_xt_by_xを一緒に処理\r
+ final double srow = Math.sqrt((double) i_number_of_data);\r
+ double w00, w11, w10;\r
+ w00 = w11 = w10 = 0.0;// *out = 0.0;\r
+ for (int i = 0; i < i_number_of_data; i++) {\r
+ final double x = (i_v1[i] - sx) / srow;\r
+ final double y = (i_v2[i] - sy) / srow;\r
+ w00 += (x * x);// *out += *in1 * *in2;\r
+ w10 += (x * y);// *out += *in1 * *in2;\r
+ w11 += (y * y);// *out += *in1 * *in2;\r
+ }\r
+ o_matrix.m00=w00;\r
+ o_matrix.m01=o_matrix.m10=w10;\r
+ o_matrix.m11=w11;\r
+ \r
+ //PCA_PCAの処理\r
+ PCA_QRM(o_matrix, o_ev);\r
+ // m2 = o_output.m;// m2 = output->m;\r
+ if (o_ev[0] < PCA_VZERO) {// if( ev->v[i] < VZERO ){\r
+ o_ev[0] = 0.0;// ev->v[i] = 0.0;\r
+ o_matrix.m00 = 0.0;// *(m2++) = 0.0;\r
+ o_matrix.m01 = 0.0;// *(m2++) = 0.0;\r
+ }\r
+\r
+ if (o_ev[1] < PCA_VZERO) {// if( ev->v[i] < VZERO ){\r
+ o_ev[1] = 0.0;// ev->v[i] = 0.0;\r
+ o_matrix.m10 = 0.0;// *(m2++) = 0.0;\r
+ o_matrix.m11 = 0.0;// *(m2++) = 0.0;\r
+ }\r
+ o_mean[0]=sx;\r
+ o_mean[1]=sy;\r
+ // }\r
+ return;\r
+ }\r
+ public void pca(double[] i_v1,double[] i_v2,int i_number_of_point,NyARDoubleMatrix22 o_evec, double[] o_ev,double[] o_mean) throws NyARException\r
+ {\r
+ PCA_PCA(i_v1,i_v2,i_number_of_point,o_evec, o_ev,o_mean);\r
+\r
+ final double sum = o_ev[0] + o_ev[1];\r
+ // For順変更禁止\r
+ o_ev[0] /= sum;// ev->v[i] /= sum;\r
+ o_ev[1] /= sum;// ev->v[i] /= sum;\r
+ return; \r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public interface INyARColorPatt extends INyARRgbRaster\r
+{\r
+ /**\r
+ * ラスタイメージからi_square部分のカラーパターンを抽出して、thisメンバに格納します。\r
+ * \r
+ * @param image\r
+ * Source raster object.\r
+ * ----\r
+ * 抽出元のラスタオブジェクト\r
+ * @param i_vertexs\r
+ * Vertexes of the square. Number of element must be 4.\r
+ * ----\r
+ * 射影変換元の4角形を構成する頂点群頂群。要素数は4であること。\r
+ * @return\r
+ * True if sucessfull; otherwise false.\r
+ * ----\r
+ * ラスターの取得に成功するとTRUE/失敗するとFALSE\r
+ * @throws NyARException\r
+ */\r
+// public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square) throws NyARException;\r
+ public boolean pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertexs) throws NyARException;\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
+ * 演算順序以外の最適化をしたもの\r
+ * \r
+ */\r
+public class NyARColorPatt_O1 implements INyARColorPatt\r
+{\r
+ private static final int AR_PATT_SAMPLE_NUM = 64;\r
+ \r
+ private int[] _patdata;\r
+ private NyARBufferReader _buf_reader;\r
+ private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+\r
+ private NyARIntSize _size;\r
+\r
+ public NyARColorPatt_O1(int i_width, int i_height)\r
+ {\r
+ //入力制限\r
+ assert i_width<=64 && i_height<=64;\r
+ \r
+ this._size=new NyARIntSize(i_width,i_height);\r
+ this._patdata = new int[i_height*i_width];\r
+ this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+ return;\r
+ }\r
+\r
+ public final int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+ public final int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+ public final NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ public final INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
+ }\r
+ public final INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
+\r
+ private final NyARMat __get_cpara_a = new NyARMat(8, 8);\r
+ private final NyARMat __get_cpara_b = new NyARMat(8, 1);\r
+ private final static double[][] __get__cpara_world = {{ 100.0, 100.0 }, { 100.0 + 10.0, 100.0 }, { 100.0 + 10.0, 100.0 + 10.0 },{ 100.0, 100.0 + 10.0 } };\r
+ \r
+ final protected boolean get_cpara(final NyARIntPoint2d[] i_vertex, NyARMat o_para)throws NyARException\r
+ {\r
+ double[][] world = __get__cpara_world;\r
+ NyARMat a = __get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
+ double[][] a_array = a.getArray();\r
+ NyARMat b = __get_cpara_b;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
+ double[][] b_array = b.getArray();\r
+ double[] a_pt0, a_pt1;\r
+ double[] world_pti;\r
+\r
+ for (int i = 0; i < 4; i++) {\r
+ a_pt0 = a_array[i * 2];\r
+ a_pt1 = a_array[i * 2 + 1];\r
+ world_pti = world[i];\r
+\r
+ a_pt0[0] = (double) world_pti[0];// a->m[i*16+0] = world[i][0];\r
+ a_pt0[1] = (double) world_pti[1];// a->m[i*16+1] = world[i][1];\r
+ a_pt0[2] = 1.0;// a->m[i*16+2] = 1.0;\r
+ a_pt0[3] = 0.0;// a->m[i*16+3] = 0.0;\r
+ a_pt0[4] = 0.0;// a->m[i*16+4] = 0.0;\r
+ a_pt0[5] = 0.0;// a->m[i*16+5] = 0.0;\r
+ a_pt0[6] = (double) (-world_pti[0] * i_vertex[i].x);// a->m[i*16+6]= -world[i][0]*vertex[i][0];\r
+ a_pt0[7] = (double) (-world_pti[1] * i_vertex[i].x);// a->m[i*16+7]=-world[i][1]*vertex[i][0];\r
+ a_pt1[0] = 0.0;// a->m[i*16+8] = 0.0;\r
+ a_pt1[1] = 0.0;// a->m[i*16+9] = 0.0;\r
+ a_pt1[2] = 0.0;// a->m[i*16+10] = 0.0;\r
+ a_pt1[3] = (double) world_pti[0];// a->m[i*16+11] = world[i][0];\r
+ a_pt1[4] = (double) world_pti[1];// a->m[i*16+12] = world[i][1];\r
+ a_pt1[5] = 1.0;// a->m[i*16+13] = 1.0;\r
+ a_pt1[6] = (double) (-world_pti[0] * i_vertex[i].y);// a->m[i*16+14]=-world[i][0]*vertex[i][1];\r
+ a_pt1[7] = (double) (-world_pti[1] * i_vertex[i].y);// a->m[i*16+15]=-world[i][1]*vertex[i][1];\r
+ b_array[i * 2 + 0][0] = (double) i_vertex[i].x;// b->m[i*2+0] =vertex[i][0];\r
+ b_array[i * 2 + 1][0] = (double) i_vertex[i].y;// b->m[i*2+1] =vertex[i][1];\r
+ }\r
+ if (!a.matrixSelfInv()) {\r
+ return false;\r
+ }\r
+\r
+ o_para.matrixMul(a, b);\r
+ return true;\r
+ } \r
+ private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
+ private final NyARMat __pickFromRaster_cpara_c = new NyARMat(8, 1);\r
+ \r
+ /**\r
+ * @see INyARColorPatt#pickFromRaster\r
+ */\r
+ public boolean pickFromRaster(INyARRgbRaster image,NyARIntPoint2d[] i_vertexs)throws NyARException\r
+ {\r
+ // パターンの切り出しに失敗することもある。\r
+ NyARMat cpara = this.__pickFromRaster_cpara_c;\r
+ if (!get_cpara(i_vertexs, cpara)) {\r
+ return false;\r
+ }\r
+ final double[][] para=cpara.getArray();\r
+ final double para00=para[0*3+0][0];\r
+ final double para01=para[0*3+1][0];\r
+ final double para02=para[0*3+2][0];\r
+ final double para10=para[1*3+0][0];\r
+ final double para11=para[1*3+1][0];\r
+ final double para12=para[1*3+2][0];\r
+ final double para20=para[2*3+0][0];\r
+ final double para21=para[2*3+1][0];\r
+ final double para22=1.0;\r
+ \r
+ int lx1 = (int) ((i_vertexs[0].x - i_vertexs[1].x) * (i_vertexs[0].x - i_vertexs[1].x) + (i_vertexs[0].y - i_vertexs[1].y)* (i_vertexs[0].y - i_vertexs[1].y));\r
+ int lx2 = (int) ((i_vertexs[2].x - i_vertexs[3].x) * (i_vertexs[2].x - i_vertexs[3].x) + (i_vertexs[2].y - i_vertexs[3].y)* (i_vertexs[2].y - i_vertexs[3].y));\r
+ int ly1 = (int) ((i_vertexs[1].x - i_vertexs[2].x) * (i_vertexs[1].x - i_vertexs[2].x) + (i_vertexs[1].y - i_vertexs[2].y)* (i_vertexs[1].y - i_vertexs[2].y));\r
+ int ly2 = (int) ((i_vertexs[3].x - i_vertexs[0].x) * (i_vertexs[3].x - i_vertexs[0].x) + (i_vertexs[3].y - i_vertexs[0].y)* (i_vertexs[3].y - i_vertexs[0].y));\r
+ if (lx2 > lx1) {\r
+ lx1 = lx2;\r
+ }\r
+ if (ly2 > ly1) {\r
+ ly1 = ly2;\r
+ }\r
+ \r
+ int sample_pixel_x = this._size.w;\r
+ int sample_pixel_y = this._size.h;\r
+ while (sample_pixel_x * sample_pixel_x < lx1 / 4) {\r
+ sample_pixel_x *= 2;\r
+ }\r
+ while (sample_pixel_y * sample_pixel_y < ly1 / 4) {\r
+ sample_pixel_y *= 2;\r
+ }\r
+\r
+ if (sample_pixel_x > AR_PATT_SAMPLE_NUM) {\r
+ sample_pixel_x = AR_PATT_SAMPLE_NUM;\r
+ }\r
+ if (sample_pixel_y > AR_PATT_SAMPLE_NUM) {\r
+ sample_pixel_y = AR_PATT_SAMPLE_NUM;\r
+ }\r
+\r
+ final int xdiv = sample_pixel_x / this._size.w;// xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
+ final int ydiv = sample_pixel_y / this._size.h;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
+\r
+\r
+ int img_x = image.getWidth();\r
+ int img_y = image.getHeight();\r
+\r
+ final double xdiv2_reciprocal = 1.0 / sample_pixel_x;\r
+ final double ydiv2_reciprocal = 1.0 / sample_pixel_y;\r
+ int r,g,b;\r
+ int[] rgb_tmp = __pickFromRaster_rgb_tmp;\r
+\r
+ //ピクセルリーダーを取得\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ final int xdiv_x_ydiv = xdiv * ydiv;\r
+\r
+ for(int iy=0;iy<this._size.h;iy++){\r
+ for(int ix=0;ix<this._size.w;ix++){\r
+ r=g=b=0;\r
+ //1ピクセルを作成\r
+ for(int j=0;j<ydiv;j++){\r
+ final double yw = 102.5 + 5.0 * (iy*ydiv+j + 0.5) * ydiv2_reciprocal; \r
+ for(int i=0;i<xdiv;i++){\r
+ final double xw = 102.5 + 5.0 * (ix*xdiv+i + 0.5) * xdiv2_reciprocal;\r
+ final double d = para20 * xw + para21 * yw+ para22;\r
+ if (d == 0) {\r
+ throw new NyARException();\r
+ }\r
+ final int xc = (int) ((para00 * xw + para01 * yw + para02) / d);\r
+ final int yc = (int) ((para10 * xw + para11 * yw + para12) / d);\r
+ \r
+ if (xc >= 0 && xc < img_x && yc >= 0 && yc < img_y) {\r
+ reader.getPixel(xc, yc, rgb_tmp);\r
+ r += rgb_tmp[0];// R\r
+ g += rgb_tmp[1];// G\r
+ b += rgb_tmp[2];// B\r
+ // System.out.println(xc+":"+yc+":"+rgb_tmp[0]+":"+rgb_tmp[1]+":"+rgb_tmp[2]);\r
+ }\r
+ }\r
+ }\r
+ this._patdata[iy*this._size.w+ix]=(((r / xdiv_x_ydiv)&0xff)<<16)|(((g / xdiv_x_ydiv)&0xff)<<8)|(((b / xdiv_x_ydiv)&0xff));\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
+ * 演算順序を含む最適化をしたもの\r
+ * \r
+ */\r
+public class NyARColorPatt_O3 implements INyARColorPatt\r
+{\r
+ private static final int AR_PATT_SAMPLE_NUM = 64;\r
+\r
+ private int[] _patdata;\r
+ private NyARBufferReader _buf_reader;\r
+ private NyARIntSize _size;\r
+ private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+ \r
+ public NyARColorPatt_O3(int i_width, int i_height)\r
+ {\r
+ this._size=new NyARIntSize(i_width,i_height);\r
+ this._patdata = new int[i_height*i_width];\r
+ this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+ }\r
+ public int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+ public int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+ public NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
+ }\r
+ public INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
+ private final NyARMat wk_get_cpara_a = new NyARMat(8, 8);\r
+ private final NyARMat wk_get_cpara_b = new NyARMat(8, 1);\r
+ private final NyARMat wk_pickFromRaster_cpara = new NyARMat(8, 1);\r
+\r
+ /**\r
+ * @param world\r
+ * @param vertex\r
+ * @param o_para\r
+ * @throws NyARException\r
+ */\r
+ private boolean get_cpara(final NyARIntPoint2d[] i_vertex, NyARMat o_para)throws NyARException\r
+ {\r
+ int[][] world = wk_pickFromRaster_world;\r
+ NyARMat a = wk_get_cpara_a;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 8 );\r
+ double[][] a_array = a.getArray();\r
+ NyARMat b = wk_get_cpara_b;// 次処理で値を設定するので、初期化不要// new NyARMat( 8, 1 );\r
+ double[][] b_array = b.getArray();\r
+ double[] a_pt0, a_pt1;\r
+ int[] world_pti;\r
+\r
+ for (int i = 0; i < 4; i++) {\r
+ a_pt0 = a_array[i * 2];\r
+ a_pt1 = a_array[i * 2 + 1];\r
+ world_pti = world[i];\r
+\r
+ a_pt0[0] = (double) world_pti[0];// a->m[i*16+0] = world[i][0];\r
+ a_pt0[1] = (double) world_pti[1];// a->m[i*16+1] = world[i][1];\r
+ a_pt0[2] = 1.0;// a->m[i*16+2] = 1.0;\r
+ a_pt0[3] = 0.0;// a->m[i*16+3] = 0.0;\r
+ a_pt0[4] = 0.0;// a->m[i*16+4] = 0.0;\r
+ a_pt0[5] = 0.0;// a->m[i*16+5] = 0.0;\r
+ a_pt0[6] = (double) (-world_pti[0] * i_vertex[i].x);// a->m[i*16+6]= -world[i][0]*vertex[i][0];\r
+ a_pt0[7] = (double) (-world_pti[1] * i_vertex[i].x);// a->m[i*16+7]=-world[i][1]*vertex[i][0];\r
+ a_pt1[0] = 0.0;// a->m[i*16+8] = 0.0;\r
+ a_pt1[1] = 0.0;// a->m[i*16+9] = 0.0;\r
+ a_pt1[2] = 0.0;// a->m[i*16+10] = 0.0;\r
+ a_pt1[3] = (double) world_pti[0];// a->m[i*16+11] = world[i][0];\r
+ a_pt1[4] = (double) world_pti[1];// a->m[i*16+12] = world[i][1];\r
+ a_pt1[5] = 1.0;// a->m[i*16+13] = 1.0;\r
+ a_pt1[6] = (double) (-world_pti[0] * i_vertex[i].y);// a->m[i*16+14]=-world[i][0]*vertex[i][1];\r
+ a_pt1[7] = (double) (-world_pti[1] * i_vertex[i].y);// a->m[i*16+15]=-world[i][1]*vertex[i][1];\r
+ b_array[i * 2 + 0][0] = (double) i_vertex[i].x;// b->m[i*2+0] =vertex[i][0];\r
+ b_array[i * 2 + 1][0] = (double) i_vertex[i].y;// b->m[i*2+1] =vertex[i][1];\r
+ }\r
+ if (!a.matrixSelfInv()) {\r
+ return false;\r
+ }\r
+\r
+ o_para.matrixMul(a, b);\r
+ return true;\r
+ }\r
+\r
+ // private final double[] wk_pickFromRaster_para=new double[9];//[3][3];\r
+ private final static int[][] wk_pickFromRaster_world = {// double world[4][2];\r
+ { 100, 100 }, { 100 + 10, 100 }, { 100 + 10, 100 + 10 }, { 100, 100 + 10 } };\r
+\r
+\r
+\r
+ /**\r
+ * @see INyARColorPatt#pickFromRaster\r
+ */\r
+ public boolean pickFromRaster(INyARRgbRaster image,NyARIntPoint2d[] i_vertexs)throws NyARException\r
+ {\r
+ NyARMat cpara = this.wk_pickFromRaster_cpara;\r
+ // xdiv2,ydiv2の計算\r
+ int xdiv2, ydiv2;\r
+ int l1, l2;\r
+ int w1, w2;\r
+ // x計算\r
+ w1 = i_vertexs[0].x - i_vertexs[1].x;\r
+ w2 = i_vertexs[0].y - i_vertexs[1].y;\r
+ l1 = (w1 * w1 + w2 * w2);\r
+ w1 = i_vertexs[2].x - i_vertexs[3].x;\r
+ w2 = i_vertexs[2].y - i_vertexs[3].y;\r
+ l2 = (w1 * w1 + w2 * w2);\r
+ if (l2 > l1) {\r
+ l1 = l2;\r
+ }\r
+ l1 = l1 / 4;\r
+ xdiv2 = this._size.w;\r
+ while (xdiv2 * xdiv2 < l1) {\r
+ xdiv2 *= 2;\r
+ }\r
+ if (xdiv2 > AR_PATT_SAMPLE_NUM) {\r
+ xdiv2 = AR_PATT_SAMPLE_NUM;\r
+ }\r
+\r
+ // y計算\r
+ w1 = i_vertexs[1].x - i_vertexs[2].x;\r
+ w2 = i_vertexs[1].y - i_vertexs[2].y;\r
+ l1 = (w1 * w1 + w2 * w2);\r
+ w1 = i_vertexs[3].x - i_vertexs[0].x;\r
+ w2 = i_vertexs[3].y - i_vertexs[0].y;\r
+ l2 = (w1 * w1 + w2 * w2);\r
+ if (l2 > l1) {\r
+ l1 = l2;\r
+ }\r
+ ydiv2 = this._size.h;\r
+ l1 = l1 / 4;\r
+ while (ydiv2 * ydiv2 < l1) {\r
+ ydiv2 *= 2;\r
+ }\r
+ if (ydiv2 > AR_PATT_SAMPLE_NUM) {\r
+ ydiv2 = AR_PATT_SAMPLE_NUM;\r
+ }\r
+\r
+ // cparaの計算\r
+ if (!get_cpara(i_vertexs, cpara)) {\r
+ return false;\r
+ }\r
+ updateExtpat(image, cpara, xdiv2, ydiv2);\r
+\r
+ return true;\r
+ }\r
+ private int[] __updateExtpat_rgbset;\r
+ private int[] __updateExtpat_xc;\r
+ private int[] __updateExtpat_yc;\r
+ private double[] __updateExtpat_xw;\r
+ private double[] __updateExtpat_yw;\r
+ private int _last_pix_resolution_x=0;\r
+ private int _last_pix_resolution_y=0;\r
+ private void reservWorkBuffers(int i_xdiv,int i_ydiv)\r
+ {\r
+ if(this._last_pix_resolution_x<i_xdiv || this._last_pix_resolution_y<i_ydiv){\r
+ this.__updateExtpat_xc=new int[i_xdiv*i_ydiv];\r
+ this.__updateExtpat_yc=new int[i_xdiv*i_ydiv];\r
+ this.__updateExtpat_xw=new double[i_xdiv];\r
+ this.__updateExtpat_yw=new double[i_ydiv];\r
+ this.__updateExtpat_rgbset=new int[i_xdiv*i_ydiv*3];\r
+ this._last_pix_resolution_x=i_xdiv;\r
+ this._last_pix_resolution_y=i_ydiv;\r
+ }\r
+ return;\r
+ }\r
+ private static double LT_POS=102.5;\r
+ private static double SQ_SIZE=5.0;\r
+ \r
+ //分割数16未満になると少し遅くなるかも。\r
+ private void updateExtpat(INyARRgbRaster image, NyARMat i_cpara, int i_xdiv2,int i_ydiv2) throws NyARException\r
+ {\r
+\r
+ int i,j;\r
+ int r,g,b;\r
+ //ピクセルリーダーを取得\r
+ final int pat_size_w=this._size.w;\r
+ final int xdiv = i_xdiv2 / pat_size_w;// xdiv = xdiv2/Config.AR_PATT_SIZE_X;\r
+ final int ydiv = i_ydiv2 / this._size.h;// ydiv = ydiv2/Config.AR_PATT_SIZE_Y;\r
+ final int xdiv_x_ydiv = xdiv * ydiv;\r
+ double reciprocal;\r
+ final double[][] para=i_cpara.getArray();\r
+ final double para00=para[0*3+0][0];\r
+ final double para01=para[0*3+1][0];\r
+ final double para02=para[0*3+2][0];\r
+ final double para10=para[1*3+0][0];\r
+ final double para11=para[1*3+1][0];\r
+ final double para12=para[1*3+2][0];\r
+ final double para20=para[2*3+0][0];\r
+ final double para21=para[2*3+1][0];\r
+\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ final int img_width=image.getWidth();\r
+ final int img_height=image.getHeight();\r
+\r
+ //ワークバッファの準備\r
+ reservWorkBuffers(xdiv,ydiv);\r
+ final double[] xw=this.__updateExtpat_xw;\r
+ final double[] yw=this.__updateExtpat_yw;\r
+ final int[] xc=this.__updateExtpat_xc;\r
+ final int[] yc=this.__updateExtpat_yc;\r
+ int[] rgb_set = this.__updateExtpat_rgbset;\r
+\r
+ \r
+ for(int iy=this._size.h-1;iy>=0;iy--){\r
+ for(int ix=pat_size_w-1;ix>=0;ix--){\r
+ //xw,ywマップを作成\r
+ reciprocal= 1.0 / i_xdiv2;\r
+ for(i=xdiv-1;i>=0;i--){\r
+ xw[i]=LT_POS + SQ_SIZE * (ix*xdiv+i + 0.5) * reciprocal;\r
+ }\r
+ reciprocal= 1.0 / i_ydiv2;\r
+ for(i=ydiv-1;i>=0;i--){\r
+ yw[i]=LT_POS + SQ_SIZE * (iy*ydiv+i + 0.5) * reciprocal;\r
+ }\r
+ //1ピクセルを構成するピクセル座標の集合をxc,yc配列に取得\r
+ int number_of_pix=0;\r
+ for(i=ydiv-1;i>=0;i--)\r
+ {\r
+ final double para01_x_yw_para02=para01 * yw[i] + para02;\r
+ final double para11_x_yw_para12=para11 * yw[i] + para12;\r
+ final double para12_x_yw_para22=para21 * yw[i]+ 1.0;\r
+ for(j=xdiv-1;j>=0;j--){\r
+ \r
+ final double d = para20 * xw[j] + para12_x_yw_para22;\r
+ if (d == 0) {\r
+ throw new NyARException();\r
+ }\r
+ final int xcw= (int) ((para00 * xw[j] + para01_x_yw_para02) / d);\r
+ final int ycw= (int) ((para10 * xw[j] + para11_x_yw_para12) / d);\r
+ if(xcw<0 || xcw>=img_width || ycw<0 ||ycw>=img_height){\r
+ continue;\r
+ }\r
+ xc[number_of_pix] =xcw;\r
+ yc[number_of_pix] =ycw;\r
+ number_of_pix++;\r
+ }\r
+ }\r
+ //1ピクセル分の配列を取得\r
+ reader.getPixelSet(xc,yc,number_of_pix, rgb_set);\r
+ r=g=b=0;\r
+ for(i=number_of_pix*3-1;i>=0;i-=3){\r
+ r += rgb_set[i-2];// R\r
+ g += rgb_set[i-1];// G\r
+ b += rgb_set[i];// B\r
+ }\r
+ //1ピクセル確定\r
+ this._patdata[iy*pat_size_w+ix]=(((r / xdiv_x_ydiv)&0xff)<<16)|(((g / xdiv_x_ydiv)&0xff)<<8)|(((b / xdiv_x_ydiv)&0xff));\r
+ }\r
+ }\r
+ return;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.NyARPerspectiveParamGenerator_O1;\r
+\r
+\r
+/**\r
+ * 遠近法を使ったパースペクティブ補正をかけて、ラスタ上の四角形から\r
+ * 任意解像度の矩形パターンを作成します。\r
+ *\r
+ */\r
+public class NyARColorPatt_Perspective implements INyARColorPatt\r
+{\r
+ protected int[] _patdata;\r
+ protected NyARIntPoint2d _pickup_lt=new NyARIntPoint2d(); \r
+ protected int _resolution;\r
+ protected NyARBufferReader _buf_reader;\r
+ protected NyARIntSize _size;\r
+ protected NyARPerspectiveParamGenerator_O1 _perspective_gen;\r
+ private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+ private static final int LOCAL_LT=1;\r
+ \r
+ private void initializeInstance(int i_width, int i_height,int i_point_per_pix)\r
+ {\r
+ assert i_width>2 && i_height>2;\r
+ this._resolution=i_point_per_pix; \r
+ this._size=new NyARIntSize(i_width,i_height);\r
+ this._patdata = new int[i_height*i_width];\r
+ this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+ return; \r
+ }\r
+ /**\r
+ * 例えば、64\r
+ * @param i_width\r
+ * 取得画像の解像度幅\r
+ * @param i_height\r
+ * 取得画像の解像度高さ\r
+ * @param i_point_per_pix\r
+ * 1ピクセルあたりの縦横サンプリング数。2なら2x2=4ポイントをサンプリングする。\r
+ */\r
+ public NyARColorPatt_Perspective(int i_width, int i_height,int i_point_per_pix)\r
+ {\r
+ initializeInstance(i_width,i_height,i_point_per_pix);\r
+ setEdgeSize(0,0,i_point_per_pix);\r
+ return;\r
+ }\r
+ /**\r
+ * 例えば、64\r
+ * @param i_width\r
+ * 取得画像の解像度幅\r
+ * @param i_height\r
+ * 取得画像の解像度高さ\r
+ * @param i_edge_percentage\r
+ * エッジ幅の割合(ARToolKit標準と同じなら、25)\r
+ */\r
+ public NyARColorPatt_Perspective(int i_width, int i_height,int i_resolution,int i_edge_percentage)\r
+ {\r
+ //入力制限\r
+ initializeInstance(i_width,i_height,i_resolution);\r
+ setEdgeSizeByPercent(i_edge_percentage,i_edge_percentage,i_resolution);\r
+ return;\r
+ } \r
+ /**\r
+ * 矩形領域のエッジサイズを指定します。\r
+ * エッジの計算方法は以下の通りです。\r
+ * 1.マーカ全体を(i_x_edge*2+width)x(i_y_edge*2+height)の解像度でパラメタを計算します。\r
+ * 2.ピクセルの取得開始位置を(i_x_edge/2,i_y_edge/2)へ移動します。\r
+ * 3.開始位置から、width x height個のピクセルを取得します。\r
+ * \r
+ * ARToolKit標準マーカの場合は、width/2,height/2を指定してください。\r
+ * @param i_x_edge\r
+ * @param i_y_edge\r
+ */\r
+ public void setEdgeSize(int i_x_edge,int i_y_edge,int i_resolution)\r
+ {\r
+ assert(i_x_edge>=0);\r
+ assert(i_y_edge>=0);\r
+ //Perspectiveパラメタ計算器を作成\r
+ this._perspective_gen=new NyARPerspectiveParamGenerator_O1(\r
+ LOCAL_LT,LOCAL_LT,\r
+ (i_x_edge*2+this._size.w)*i_resolution,\r
+ (i_y_edge*2+this._size.h)*i_resolution);\r
+ //ピックアップ開始位置を計算\r
+ this._pickup_lt.x=i_x_edge*i_resolution+LOCAL_LT;\r
+ this._pickup_lt.y=i_y_edge*i_resolution+LOCAL_LT;\r
+ return;\r
+ }\r
+ public void setEdgeSizeByPercent(int i_x_percent,int i_y_percent,int i_resolution)\r
+ {\r
+ assert(i_x_percent>=0);\r
+ assert(i_y_percent>=0);\r
+ setEdgeSize(this._size.w*i_x_percent/50,this._size.h*i_y_percent/50,i_resolution);\r
+ return;\r
+ }\r
+\r
+ \r
+ public final int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+ public final int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+ public final NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ public final INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
+ }\r
+ public final INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
+ private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
+ protected final double[] __pickFromRaster_cpara=new double[8];\r
+ \r
+ /**\r
+ * @see INyARColorPatt#pickFromRaster\r
+ */\r
+ public boolean pickFromRaster(INyARRgbRaster image,NyARIntPoint2d[] i_vertexs)throws NyARException\r
+ {\r
+ //遠近法のパラメータを計算\r
+ final double[] cpara = this.__pickFromRaster_cpara;\r
+ if (!this._perspective_gen.getParam(i_vertexs, cpara)) {\r
+ return false;\r
+ }\r
+ \r
+ final int resolution=this._resolution;\r
+ final int img_x = image.getWidth();\r
+ final int img_y = image.getHeight();\r
+ final int res_pix=resolution*resolution;\r
+\r
+ final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
+\r
+ //ピクセルリーダーを取得\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ int p=0;\r
+ for(int iy=0;iy<this._size.h*resolution;iy+=resolution){\r
+ //解像度分の点を取る。\r
+ for(int ix=0;ix<this._size.w*resolution;ix+=resolution){\r
+ int r,g,b;\r
+ r=g=b=0;\r
+ for(int i2y=iy;i2y<iy+resolution;i2y++){\r
+ int cy=this._pickup_lt.y+i2y;\r
+ for(int i2x=ix;i2x<ix+resolution;i2x++){\r
+ //1ピクセルを作成\r
+ int cx=this._pickup_lt.x+i2x;\r
+ final double d=cpara[6]*cx+cpara[7]*cy+1.0;\r
+ int x=(int)((cpara[0]*cx+cpara[1]*cy+cpara[2])/d);\r
+ int y=(int)((cpara[3]*cx+cpara[4]*cy+cpara[5])/d);\r
+ if(x<0){x=0;}\r
+ if(x>=img_x){x=img_x-1;}\r
+ if(y<0){y=0;}\r
+ if(y>=img_y){y=img_y-1;}\r
+ \r
+ reader.getPixel(x, y, rgb_tmp);\r
+ r+=rgb_tmp[0];\r
+ g+=rgb_tmp[1];\r
+ b+=rgb_tmp[2];\r
+ }\r
+ }\r
+ r/=res_pix;\r
+ g/=res_pix;\r
+ b/=res_pix;\r
+ this._patdata[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));\r
+ p++;\r
+ }\r
+ }\r
+ //ピクセル問い合わせ\r
+ //ピクセルセット\r
+ return true;\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+\r
+interface IpickFromRaster_Impl\r
+{\r
+ public void pickFromRaster(double[] i_cpara,INyARRgbRaster image, int[] o_patt)throws NyARException;\r
+}\r
+\r
+/**\r
+ * 汎用ピックアップ関数\r
+ *\r
+ */\r
+class pickFromRaster_N implements IpickFromRaster_Impl\r
+{\r
+ protected int _resolution;\r
+ protected NyARIntSize _size_ref;\r
+ protected NyARIntPoint2d _lt_ref;\r
+ public pickFromRaster_N(NyARIntPoint2d i_lt,int i_resolution,NyARIntSize i_source_size)\r
+ {\r
+ this._lt_ref=i_lt;\r
+ this._resolution=i_resolution;\r
+ this._size_ref=i_source_size;\r
+ \r
+ this._rgb_temp=new int[i_resolution*i_resolution*3];\r
+ this._rgb_px=new int[i_resolution*i_resolution];\r
+ this._rgb_py=new int[i_resolution*i_resolution];\r
+ \r
+ this._cp1cy_cp2=new double[i_resolution];\r
+ this._cp4cy_cp5=new double[i_resolution];\r
+ this._cp7cy_1=new double[i_resolution];\r
+ return;\r
+ }\r
+ private int[] _rgb_temp;\r
+ private int[] _rgb_px;\r
+ private int[] _rgb_py;\r
+ private double[] _cp1cy_cp2;\r
+ private double[] _cp4cy_cp5;\r
+ private double[] _cp7cy_1;\r
+ \r
+ public void pickFromRaster(double[] i_cpara,INyARRgbRaster image,int[] o_patt)throws NyARException\r
+ {\r
+ int i2x,i2y;//プライム変数\r
+ int x,y;\r
+ int w;\r
+ int r,g,b;\r
+\r
+ final int resolution=this._resolution;\r
+ final int res_pix=resolution*resolution;\r
+ final int img_x = image.getWidth();\r
+ final int img_y = image.getHeight();\r
+\r
+ final int[] rgb_tmp = this._rgb_temp;\r
+ final int[] rgb_px=this._rgb_px;\r
+ final int[] rgb_py=this._rgb_py; \r
+\r
+ final double[] cp1cy_cp2=this._cp1cy_cp2;\r
+ final double[] cp4cy_cp5=this._cp4cy_cp5;\r
+ final double[] cp7cy_1=this._cp7cy_1; \r
+\r
+ final double cp0=i_cpara[0];\r
+ final double cp3=i_cpara[3];\r
+ final double cp6=i_cpara[6];\r
+ final double cp1=i_cpara[1];\r
+ final double cp2=i_cpara[2];\r
+ final double cp4=i_cpara[4];\r
+ final double cp5=i_cpara[5];\r
+ final double cp7=i_cpara[7];\r
+ \r
+ \r
+ final int pick_y=this._lt_ref.y;\r
+ final int pick_x=this._lt_ref.x;\r
+ //ピクセルリーダーを取得\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ int p=0;\r
+\r
+ \r
+ for(int iy=0;iy<this._size_ref.h*resolution;iy+=resolution){\r
+ w=pick_y+iy;\r
+ cp1cy_cp2[0]=cp1*w+cp2;\r
+ cp4cy_cp5[0]=cp4*w+cp5;\r
+ cp7cy_1[0]=cp7*w+1.0; \r
+ for(i2y=1;i2y<resolution;i2y++){\r
+ cp1cy_cp2[i2y]=cp1cy_cp2[i2y-1]+cp1;\r
+ cp4cy_cp5[i2y]=cp4cy_cp5[i2y-1]+cp4;\r
+ cp7cy_1[i2y]=cp7cy_1[i2y-1]+cp7;\r
+ }\r
+ //解像度分の点を取る。\r
+\r
+ for(int ix=0;ix<this._size_ref.w*resolution;ix+=resolution){\r
+ int n=0;\r
+ w=pick_x+ix;\r
+ for(i2y=resolution-1;i2y>=0;i2y--){\r
+ double cp0cx=cp0*w+cp1cy_cp2[i2y];\r
+ double cp6cx=cp6*w+cp7cy_1[i2y];\r
+ double cp3cx=cp3*w+cp4cy_cp5[i2y];\r
+ \r
+ final double m=1/(cp6cx);\r
+ final double d=-cp6/(cp6cx*(cp6cx+cp6));\r
+ \r
+ double m2=cp0cx*m;\r
+ double m3=cp3cx*m;\r
+ double d2=cp0cx*d+cp0*(m+d);\r
+ double d3=cp3cx*d+cp3*(m+d);\r
+ for(i2x=resolution-1;i2x>=0;i2x--){\r
+ //1ピクセルを作成\r
+ x=rgb_px[n]=(int)(m2);\r
+ y=rgb_py[n]=(int)(m3);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[n]=0;}else if(x>=img_x){rgb_px[n]=img_x-1;}\r
+ if(y<0){rgb_py[n]=0;}else if(y>=img_y){rgb_py[n]=img_y-1;} \r
+ }\r
+ n++;\r
+ m2+=d2;\r
+ m3+=d3;\r
+ }\r
+ }\r
+ reader.getPixelSet(rgb_px, rgb_py,res_pix, rgb_tmp);\r
+ r=g=b=0;\r
+ for(int i=res_pix*3-1;i>0;){\r
+ b+=rgb_tmp[i--];\r
+ g+=rgb_tmp[i--];\r
+ r+=rgb_tmp[i--];\r
+ }\r
+ r/=res_pix;\r
+ g/=res_pix;\r
+ b/=res_pix;\r
+ o_patt[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));\r
+ p++;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+}\r
+/**\r
+ * チェックデジット:4127936236942444153655776299710081208144715171590159116971715177917901890204024192573274828522936312731813388371037714083\r
+ *\r
+ */\r
+class pickFromRaster_1 implements IpickFromRaster_Impl\r
+{\r
+ protected NyARIntSize _size_ref;\r
+ protected NyARIntPoint2d _lt_ref;\r
+ public pickFromRaster_1(NyARIntPoint2d i_lt,NyARIntSize i_source_size)\r
+ {\r
+ this._lt_ref=i_lt;\r
+ this._size_ref=i_source_size;\r
+ \r
+ this._rgb_temp=new int[i_source_size.w*3];\r
+ this._rgb_px=new int[i_source_size.w];\r
+ this._rgb_py=new int[i_source_size.w];\r
+ \r
+ return;\r
+ }\r
+ private int[] _rgb_temp;\r
+ private int[] _rgb_px;\r
+ private int[] _rgb_py;\r
+\r
+ \r
+ public void pickFromRaster(double[] i_cpara,INyARRgbRaster image,int[] o_patt)throws NyARException\r
+ {\r
+ double d0,m0;\r
+ int x,y;\r
+ \r
+ final int img_x = image.getWidth();\r
+ final int img_y = image.getHeight();\r
+ final int patt_w=this._size_ref.w;\r
+\r
+ final int[] rgb_tmp = this._rgb_temp;\r
+ final int[] rgb_px=this._rgb_px;\r
+ final int[] rgb_py=this._rgb_py; \r
+\r
+ \r
+\r
+ final double cp0=i_cpara[0];\r
+ final double cp3=i_cpara[3];\r
+ final double cp6=i_cpara[6];\r
+ final double cp1=i_cpara[1];\r
+ final double cp4=i_cpara[4];\r
+ final double cp7=i_cpara[7];\r
+ \r
+ \r
+ final int pick_y=this._lt_ref.y;\r
+ final int pick_x=this._lt_ref.x;\r
+ //ピクセルリーダーを取得\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ int p=0;\r
+\r
+ \r
+ double cp0cx0,cp3cx0;\r
+ double cp1cy_cp20=cp1*pick_y+i_cpara[2]+cp0*pick_x;\r
+ double cp4cy_cp50=cp4*pick_y+i_cpara[5]+cp3*pick_x;\r
+ double cp7cy_10=cp7*pick_y+1.0+cp6*pick_x;\r
+ \r
+\r
+ for(int iy=this._size_ref.h-1;iy>=0;iy--){\r
+ m0=1/(cp7cy_10);\r
+ d0=-cp6/(cp7cy_10*(cp7cy_10+cp6)); \r
+\r
+ cp0cx0=cp1cy_cp20;\r
+ cp3cx0=cp4cy_cp50;\r
+ \r
+ //ピックアップシーケンス\r
+ \r
+ //0番目のピクセル(検査対象)をピックアップ\r
+\r
+\r
+ for(int ix=patt_w-1;ix>=0;ix--){\r
+ //1ピクセルを作成\r
+ x=rgb_px[ix]=(int)(cp0cx0*m0);\r
+ y=rgb_py[ix]=(int)(cp3cx0*m0);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[ix]=0;}else if(x>=img_x){rgb_px[ix]=img_x-1;}\r
+ if(y<0){rgb_py[ix]=0;}else if(y>=img_y){rgb_py[ix]=img_y-1;} \r
+ }\r
+ cp0cx0+=cp0;\r
+ cp3cx0+=cp3;\r
+ m0+=d0;\r
+ }\r
+ \r
+ cp1cy_cp20+=cp1;\r
+ cp4cy_cp50+=cp4;\r
+ cp7cy_10+=cp7;\r
+ \r
+ reader.getPixelSet(rgb_px, rgb_py,patt_w, rgb_tmp);\r
+ for(int ix=patt_w-1;ix>=0;ix--){\r
+ final int idx=ix*3;\r
+ o_patt[p]=(rgb_tmp[idx]<<16)|(rgb_tmp[idx+1]<<8)|((rgb_tmp[idx+2]&0xff));\r
+ p++;\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+}\r
+\r
+/**\r
+ * 2x2\r
+ * チェックデジット:207585881161241401501892422483163713744114324414474655086016467027227327958629279571017\r
+ *\r
+ */\r
+class pickFromRaster_2x implements IpickFromRaster_Impl\r
+{\r
+ protected NyARIntSize _size_ref;\r
+ protected NyARIntPoint2d _lt_ref;\r
+ public pickFromRaster_2x(NyARIntPoint2d i_lt,NyARIntSize i_source_size)\r
+ {\r
+ this._lt_ref=i_lt;\r
+ this._size_ref=i_source_size;\r
+ \r
+ this._rgb_temp=new int[i_source_size.w*4*3];\r
+ this._rgb_px=new int[i_source_size.w*4];\r
+ this._rgb_py=new int[i_source_size.w*4];\r
+ \r
+\r
+ return;\r
+ }\r
+ private int[] _rgb_temp;\r
+ private int[] _rgb_px;\r
+ private int[] _rgb_py;\r
+\r
+\r
+ public void pickFromRaster(double[] i_cpara,INyARRgbRaster image,int[] o_patt)throws NyARException\r
+ {\r
+ double d0,m0,d1,m1;\r
+ int x,y;\r
+ \r
+ final int img_x = image.getWidth();\r
+ final int img_y = image.getHeight();\r
+ final int patt_w=this._size_ref.w;\r
+\r
+ final int[] rgb_tmp = this._rgb_temp;\r
+ final int[] rgb_px=this._rgb_px;\r
+ final int[] rgb_py=this._rgb_py; \r
+\r
+ \r
+\r
+ final double cp0=i_cpara[0];\r
+ final double cp3=i_cpara[3];\r
+ final double cp6=i_cpara[6];\r
+ final double cp1=i_cpara[1];\r
+ final double cp4=i_cpara[4];\r
+ final double cp7=i_cpara[7];\r
+ \r
+ \r
+ final int pick_y=this._lt_ref.y;\r
+ final int pick_x=this._lt_ref.x;\r
+ //ピクセルリーダーを取得\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ int p=0;\r
+\r
+ \r
+ double cp0cx0,cp3cx0;\r
+ double cp1cy_cp20=cp1*pick_y+i_cpara[2]+cp0*pick_x;\r
+ double cp4cy_cp50=cp4*pick_y+i_cpara[5]+cp3*pick_x;\r
+ double cp7cy_10=cp7*pick_y+1.0+cp6*pick_x;\r
+\r
+\r
+ double cp0cx1,cp3cx1;\r
+ double cp1cy_cp21=cp1cy_cp20+cp1;\r
+ double cp4cy_cp51=cp4cy_cp50+cp4;\r
+ double cp7cy_11=cp7cy_10+cp7;\r
+ \r
+ double cw0=cp1+cp1;\r
+ double cw7=cp7+cp7;\r
+ double cw4=cp4+cp4;\r
+ \r
+ for(int iy=this._size_ref.h-1;iy>=0;iy--){ \r
+ cp0cx0=cp1cy_cp20;\r
+ cp3cx0=cp4cy_cp50;\r
+ cp0cx1=cp1cy_cp21;\r
+ cp3cx1=cp4cy_cp51;\r
+\r
+ m0=1/(cp7cy_10);\r
+ d0=-cp6/(cp7cy_10*(cp7cy_10+cp6)); \r
+ m1=1/(cp7cy_11);\r
+ d1=-cp6/(cp7cy_11*(cp7cy_11+cp6)); \r
+ \r
+ int n=patt_w*2*2-1;\r
+ \r
+ for(int ix=patt_w*2-1;ix>=0;ix--){\r
+ //[n,0]\r
+ x=rgb_px[n]=(int)(cp0cx0*m0);\r
+ y=rgb_py[n]=(int)(cp3cx0*m0);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[n]=0;}else if(x>=img_x){rgb_px[n]=img_x-1;}\r
+ if(y<0){rgb_py[n]=0;}else if(y>=img_y){rgb_py[n]=img_y-1;} \r
+ }\r
+ cp0cx0+=cp0;\r
+ cp3cx0+=cp3;\r
+ m0+=d0;\r
+ n--;\r
+ //[n,1]\r
+ x=rgb_px[n]=(int)(cp0cx1*m1);\r
+ y=rgb_py[n]=(int)(cp3cx1*m1);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[n]=0;}else if(x>=img_x){rgb_px[n]=img_x-1;}\r
+ if(y<0){rgb_py[n]=0;}else if(y>=img_y){rgb_py[n]=img_y-1;} \r
+ }\r
+ cp0cx1+=cp0;\r
+ cp3cx1+=cp3;\r
+ m1+=d1;\r
+ n--; \r
+ }\r
+ cp7cy_10+=cw7;\r
+ cp7cy_11+=cw7;\r
+\r
+ cp1cy_cp20+=cw0;\r
+ cp4cy_cp50+=cw4;\r
+ cp1cy_cp21+=cw0;\r
+ cp4cy_cp51+=cw4;\r
+\r
+\r
+\r
+ reader.getPixelSet(rgb_px, rgb_py,patt_w*4, rgb_tmp);\r
+ for(int ix=patt_w-1;ix>=0;ix--){\r
+ final int idx=ix*12;//3*2*2\r
+ final int r=(rgb_tmp[idx+0]+rgb_tmp[idx+3]+rgb_tmp[idx+6]+rgb_tmp[idx+ 9])/4;\r
+ final int g=(rgb_tmp[idx+1]+rgb_tmp[idx+4]+rgb_tmp[idx+7]+rgb_tmp[idx+10])/4;\r
+ final int b=(rgb_tmp[idx+2]+rgb_tmp[idx+5]+rgb_tmp[idx+8]+rgb_tmp[idx+11])/4;\r
+ o_patt[p]=(r<<16)|(g<<8)|((b&0xff));\r
+ p++;\r
+ }\r
+ }\r
+\r
+ return;\r
+ }\r
+}\r
+\r
+/**\r
+ * 4x4\r
+ *\r
+ */\r
+class pickFromRaster_4x implements IpickFromRaster_Impl\r
+{\r
+ protected NyARIntSize _size_ref;\r
+ protected NyARIntPoint2d _lt_ref;\r
+ public pickFromRaster_4x(NyARIntPoint2d i_lt,NyARIntSize i_source_size)\r
+ {\r
+ this._lt_ref=i_lt;\r
+ this._size_ref=i_source_size;\r
+ \r
+ this._rgb_temp=new int[4*4*3];\r
+ this._rgb_px=new int[4*4];\r
+ this._rgb_py=new int[4*4];\r
+ return;\r
+ }\r
+ private int[] _rgb_temp;\r
+ private int[] _rgb_px;\r
+ private int[] _rgb_py;\r
+ \r
+ public void pickFromRaster(double[] i_cpara,INyARRgbRaster image,int[] o_patt)throws NyARException\r
+ {\r
+ int x,y;\r
+ double d,m;\r
+ double cp6cx,cp0cx,cp3cx;\r
+ final int[] rgb_px=this._rgb_px;\r
+ final int[] rgb_py=this._rgb_py;\r
+\r
+ int r,g,b; \r
+ //遠近法のパラメータを計算\r
+ \r
+ final int img_x = image.getWidth();\r
+ final int img_y = image.getHeight();\r
+ final int[] rgb_tmp = this._rgb_temp;\r
+ final double cp0=i_cpara[0];\r
+ final double cp3=i_cpara[3];\r
+ final double cp6=i_cpara[6];\r
+ final double cp1=i_cpara[1];\r
+ final double cp2=i_cpara[2];\r
+ final double cp4=i_cpara[4];\r
+ final double cp5=i_cpara[5];\r
+ final double cp7=i_cpara[7];\r
+ \r
+\r
+ final int pick_lt_x=this._lt_ref.x;\r
+ //ピクセルリーダーを取得\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ \r
+\r
+ int p=0;\r
+ int py=this._lt_ref.y;\r
+ for(int iy=this._size_ref.h-1;iy>=0;iy--,py+=4){\r
+ final double cp1cy_cp2_0=cp1*py+cp2;\r
+ final double cp4cy_cp5_0=cp4*py+cp5;\r
+ final double cp7cy_1_0 =cp7*py+1.0;\r
+ \r
+ final double cp1cy_cp2_1=cp1cy_cp2_0+cp1;\r
+ final double cp1cy_cp2_2=cp1cy_cp2_1+cp1;\r
+ final double cp1cy_cp2_3=cp1cy_cp2_2+cp1;\r
+\r
+ final double cp4cy_cp5_1=cp4cy_cp5_0+cp4;\r
+ final double cp4cy_cp5_2=cp4cy_cp5_1+cp4;\r
+ final double cp4cy_cp5_3=cp4cy_cp5_2+cp4;\r
+ \r
+ int px=pick_lt_x;\r
+ //解像度分の点を取る。\r
+ for(int ix=this._size_ref.w-1;ix>=0;ix--,px+=4){\r
+\r
+ cp6cx=cp6*px;\r
+ cp0cx=cp0*px; \r
+ cp3cx=cp3*px;\r
+ \r
+ cp6cx+=cp7cy_1_0;\r
+ m=1/cp6cx;\r
+ d=-cp7/((cp6cx+cp7)*cp6cx); \r
+\r
+ //1ピクセルを作成[0,0]\r
+ x=rgb_px[0]=(int)((cp0cx+cp1cy_cp2_0)*m);\r
+ y=rgb_py[0]=(int)((cp3cx+cp4cy_cp5_0)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[0]=0;}else if(x>=img_x){rgb_px[0]=img_x-1;}\r
+ if(y<0){rgb_py[0]=0;}else if(y>=img_y){rgb_py[0]=img_y-1;} \r
+ }\r
+\r
+ //1ピクセルを作成[0,1]\r
+ m+=d; \r
+ x=rgb_px[4]=(int)((cp0cx+cp1cy_cp2_1)*m);\r
+ y=rgb_py[4]=(int)((cp3cx+cp4cy_cp5_1)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[4]=0;}else if(x>=img_x){rgb_px[4]=img_x-1;}\r
+ if(y<0){rgb_py[4]=0;}else if(y>=img_y){rgb_py[4]=img_y-1;} \r
+ } \r
+ //1ピクセルを作成[0,2]\r
+ m+=d;\r
+ x=rgb_px[8]=(int)((cp0cx+cp1cy_cp2_2)*m);\r
+ y=rgb_py[8]=(int)((cp3cx+cp4cy_cp5_2)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[8]=0;}else if(x>=img_x){rgb_px[8]=img_x-1;}\r
+ if(y<0){rgb_py[8]=0;}else if(y>=img_y){rgb_py[8]=img_y-1;} \r
+ }\r
+ \r
+ //1ピクセルを作成[0,3]\r
+ m+=d;\r
+ x=rgb_px[12]=(int)((cp0cx+cp1cy_cp2_3)*m);\r
+ y=rgb_py[12]=(int)((cp3cx+cp4cy_cp5_3)*m); \r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[12]=0;}else if(x>=img_x){rgb_px[12]=img_x-1;}\r
+ if(y<0){rgb_py[12]=0;}else if(y>=img_y){rgb_py[12]=img_y-1;} \r
+ }\r
+ \r
+ cp6cx+=cp6;\r
+ cp0cx+=cp0;\r
+ cp3cx+=cp3;\r
+ \r
+ m=1/cp6cx;\r
+ d=-cp7/((cp6cx+cp7)*cp6cx); \r
+ \r
+ //1ピクセルを作成[1,0]\r
+ x=rgb_px[1]=(int)((cp0cx+cp1cy_cp2_0)*m);\r
+ y=rgb_py[1]=(int)((cp3cx+cp4cy_cp5_0)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[1]=0;}else if(x>=img_x){rgb_px[1]=img_x-1;}\r
+ if(y<0){rgb_py[1]=0;}else if(y>=img_y){rgb_py[1]=img_y-1;}\r
+ }\r
+ //1ピクセルを作成[1,1]\r
+ m+=d;\r
+ x=rgb_px[5]=(int)((cp0cx+cp1cy_cp2_1)*m);\r
+ y=rgb_py[5]=(int)((cp3cx+cp4cy_cp5_1)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[5]=0;}else if(x>=img_x){rgb_px[5]=img_x-1;}\r
+ if(y<0){rgb_py[5]=0;}else if(y>=img_y){rgb_py[5]=img_y-1;}\r
+ }\r
+ //1ピクセルを作成[1,2]\r
+ m+=d;\r
+ x=rgb_px[9]=(int)((cp0cx+cp1cy_cp2_2)*m);\r
+ y=rgb_py[9]=(int)((cp3cx+cp4cy_cp5_2)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[9]=0;}else if(x>=img_x){rgb_px[9]=img_x-1;}\r
+ if(y<0){rgb_py[9]=0;}else if(y>=img_y){rgb_py[9]=img_y-1;}\r
+ }\r
+ //1ピクセルを作成[1,3]\r
+ m+=d;\r
+ x=rgb_px[13]=(int)((cp0cx+cp1cy_cp2_3)*m);\r
+ y=rgb_py[13]=(int)((cp3cx+cp4cy_cp5_3)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[13]=0;}else if(x>=img_x){rgb_px[13]=img_x-1;}\r
+ if(y<0){rgb_py[13]=0;}else if(y>=img_y){rgb_py[13]=img_y-1;}\r
+ }\r
+ \r
+ cp6cx+=cp6;\r
+ cp0cx+=cp0;\r
+ cp3cx+=cp3;\r
+\r
+ m=1/cp6cx;\r
+ d=-cp7/((cp6cx+cp7)*cp6cx);\r
+ \r
+ //1ピクセルを作成[2,0]\r
+ x=rgb_px[2]=(int)((cp0cx+cp1cy_cp2_0)*m);\r
+ y=rgb_py[2]=(int)((cp3cx+cp4cy_cp5_0)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[2]=0;}else if(x>=img_x){rgb_px[2]=img_x-1;}\r
+ if(y<0){rgb_py[2]=0;}else if(y>=img_y){rgb_py[2]=img_y-1;}\r
+ } \r
+ //1ピクセルを作成[2,1]\r
+ m+=d;\r
+ x=rgb_px[6]=(int)((cp0cx+cp1cy_cp2_1)*m);\r
+ y=rgb_py[6]=(int)((cp3cx+cp4cy_cp5_1)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[6]=0;}else if(x>=img_x){rgb_px[6]=img_x-1;}\r
+ if(y<0){rgb_py[6]=0;}else if(y>=img_y){rgb_py[6]=img_y-1;}\r
+ }\r
+ //1ピクセルを作成[2,2]\r
+ m+=d;\r
+ x=rgb_px[10]=(int)((cp0cx+cp1cy_cp2_2)*m);\r
+ y=rgb_py[10]=(int)((cp3cx+cp4cy_cp5_2)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[10]=0;}else if(x>=img_x){rgb_px[10]=img_x-1;}\r
+ if(y<0){rgb_py[10]=0;}else if(y>=img_y){rgb_py[10]=img_y-1;}\r
+ }\r
+ //1ピクセルを作成[2,3](ここ計算ずれします。)\r
+ m+=d;\r
+ x=rgb_px[14]=(int)((cp0cx+cp1cy_cp2_3)*m);\r
+ y=rgb_py[14]=(int)((cp3cx+cp4cy_cp5_3)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[14]=0;}else if(x>=img_x){rgb_px[14]=img_x-1;}\r
+ if(y<0){rgb_py[14]=0;}else if(y>=img_y){rgb_py[14]=img_y-1;}\r
+ }\r
+ cp6cx+=cp6;\r
+ cp0cx+=cp0;\r
+ cp3cx+=cp3;\r
+\r
+ m=1/cp6cx;\r
+ d=-cp7/((cp6cx+cp7)*cp6cx);\r
+ \r
+ //1ピクセルを作成[3,0]\r
+ x=rgb_px[3]=(int)((cp0cx+cp1cy_cp2_0)*m);\r
+ y=rgb_py[3]=(int)((cp3cx+cp4cy_cp5_0)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[3]=0;}else if(x>=img_x){rgb_px[3]=img_x-1;}\r
+ if(y<0){rgb_py[3]=0;}else if(y>=img_y){rgb_py[3]=img_y-1;}\r
+ }\r
+ //1ピクセルを作成[3,1]\r
+ m+=d;\r
+ x=rgb_px[7]=(int)((cp0cx+cp1cy_cp2_1)*m);\r
+ y=rgb_py[7]=(int)((cp3cx+cp4cy_cp5_1)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[7]=0;}else if(x>=img_x){rgb_px[7]=img_x-1;}\r
+ if(y<0){rgb_py[7]=0;}else if(y>=img_y){rgb_py[7]=img_y-1;}\r
+ }\r
+ //1ピクセルを作成[3,2]\r
+ m+=d;\r
+ x=rgb_px[11]=(int)((cp0cx+cp1cy_cp2_2)*m);\r
+ y=rgb_py[11]=(int)((cp3cx+cp4cy_cp5_2)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[11]=0;}else if(x>=img_x){rgb_px[11]=img_x-1;}\r
+ if(y<0){rgb_py[11]=0;}else if(y>=img_y){rgb_py[11]=img_y-1;}\r
+ }\r
+ //1ピクセルを作成[3,3]\r
+ m+=d;\r
+ x=rgb_px[15]=(int)((cp0cx+cp1cy_cp2_3)*m);\r
+ y=rgb_py[15]=(int)((cp3cx+cp4cy_cp5_3)*m);\r
+ if(x<0||x>=img_x||y<0||y>=img_y){\r
+ if(x<0){rgb_px[15]=0;}else if(x>=img_x){rgb_px[15]=img_x-1;}\r
+ if(y<0){rgb_py[15]=0;}else if(y>=img_y){rgb_py[15]=img_y-1;}\r
+ }\r
+\r
+ reader.getPixelSet(rgb_px, rgb_py,4*4, rgb_tmp);\r
+\r
+ r=(rgb_tmp[ 0]+rgb_tmp[ 3]+rgb_tmp[ 6]+rgb_tmp[ 9]+rgb_tmp[12]+rgb_tmp[15]+rgb_tmp[18]+rgb_tmp[21]+rgb_tmp[24]+rgb_tmp[27]+rgb_tmp[30]+rgb_tmp[33]+rgb_tmp[36]+rgb_tmp[39]+rgb_tmp[42]+rgb_tmp[45])/16;\r
+ g=(rgb_tmp[ 1]+rgb_tmp[ 4]+rgb_tmp[ 7]+rgb_tmp[10]+rgb_tmp[13]+rgb_tmp[16]+rgb_tmp[19]+rgb_tmp[22]+rgb_tmp[25]+rgb_tmp[28]+rgb_tmp[31]+rgb_tmp[34]+rgb_tmp[37]+rgb_tmp[40]+rgb_tmp[43]+rgb_tmp[46])/16;\r
+ b=(rgb_tmp[ 2]+rgb_tmp[ 5]+rgb_tmp[ 8]+rgb_tmp[11]+rgb_tmp[14]+rgb_tmp[17]+rgb_tmp[20]+rgb_tmp[23]+rgb_tmp[26]+rgb_tmp[29]+rgb_tmp[32]+rgb_tmp[35]+rgb_tmp[38]+rgb_tmp[41]+rgb_tmp[44]+rgb_tmp[47])/16;\r
+ o_patt[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));\r
+ p++;\r
+ \r
+ }\r
+ }\r
+ return;\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * 遠近法を使ったパースペクティブ補正をかけて、ラスタ上の四角形から\r
+ * 任意解像度の矩形パターンを作成します。\r
+ *\r
+ */\r
+public class NyARColorPatt_Perspective_O2 extends NyARColorPatt_Perspective\r
+{\r
+ private IpickFromRaster_Impl _pickup;\r
+ public NyARColorPatt_Perspective_O2(int i_width, int i_height,int i_resolution,int i_edge_percentage)\r
+ {\r
+ super(i_width,i_height,i_resolution,i_edge_percentage);\r
+ switch(i_resolution){\r
+ case 1:\r
+ this._pickup=new pickFromRaster_1(this._pickup_lt,this._size);\r
+ break;\r
+ case 2:\r
+ this._pickup=new pickFromRaster_2x(this._pickup_lt,this._size);\r
+ break;\r
+ case 4:\r
+ this._pickup=new pickFromRaster_4x(this._pickup_lt,this._size);\r
+ break;\r
+ default:\r
+ this._pickup=new pickFromRaster_N(this._pickup_lt,i_resolution,this._size);\r
+ } \r
+ return;\r
+ }\r
+ /**\r
+ * @see INyARColorPatt#pickFromRaster\r
+ */\r
+ public boolean pickFromRaster(INyARRgbRaster image,NyARIntPoint2d[] i_vertexs)throws NyARException\r
+ {\r
+ //遠近法のパラメータを計算\r
+ final double[] cpara = this.__pickFromRaster_cpara;\r
+ if (!this._perspective_gen.getParam(i_vertexs, cpara)) {\r
+ return false;\r
+ } \r
+ this._pickup.pickFromRaster(cpara, image,this._patdata);\r
+ return true;\r
+ }\r
+\r
+}\r
+\r
+
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.pickup;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+\r
+\r
+\r
+/**\r
+ * 疑似アフィン変換を使用して、ラスタ上の四角形から任意解像度\r
+ * の矩形パターンを作成します。\r
+ *\r
+ */\r
+public class NyARColorPatt_PseudoAffine implements INyARColorPatt\r
+{\r
+ private int[] _patdata;\r
+ private NyARBufferReader _buf_reader;\r
+ private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+ private NyARIntSize _size;\r
+ \r
+ public final int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+ \r
+ public final int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+ \r
+ public final NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ \r
+ public final INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
+ }\r
+ \r
+ public final INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
+ NyARDoubleMatrix44 _invmat=new NyARDoubleMatrix44();\r
+ /**\r
+ * @param i_width\r
+ * @param i_height\r
+ */\r
+ public NyARColorPatt_PseudoAffine(int i_width, int i_height)\r
+ { \r
+ this._size=new NyARIntSize(i_width,i_height);\r
+ this._patdata = new int[i_height*i_width];\r
+ this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+ //疑似アフィン変換のパラメタマトリクスを計算します。\r
+ //長方形から計算すると、有効要素がm00,m01,m02,m03,m10,m11,m20,m23,m30になります。\r
+ final NyARDoubleMatrix44 mat=this._invmat;\r
+ mat.m00=0;\r
+ mat.m01=0;\r
+ mat.m02=0;\r
+ mat.m03=1.0;\r
+ mat.m10=0;\r
+ mat.m11=i_width-1;\r
+ mat.m12=0;\r
+ mat.m13=1.0;\r
+ mat.m20=(i_width-1)*(i_height-1);\r
+ mat.m21=i_width-1;\r
+ mat.m22=i_height-1;\r
+ mat.m23=1.0;\r
+ mat.m30=0;\r
+ mat.m31=0;\r
+ mat.m32=i_height-1;\r
+ mat.m33=1.0;\r
+ mat.inverse(mat);\r
+ return;\r
+ } \r
+\r
+ /**\r
+ * 変換行列と頂点座標から、パラメータを計算\r
+ * o_paramの[0..3]にはXのパラメタ、[4..7]にはYのパラメタを格納する。\r
+ * @param i_vertex\r
+ * @param pa\r
+ * @param pb\r
+ */\r
+ private void calcPara(NyARIntPoint2d[] i_vertex,double[] o_cparam)\r
+ {\r
+ final NyARDoubleMatrix44 invmat=this._invmat;\r
+ double v1,v2,v4;\r
+ //変換行列とベクトルの積から、変換パラメタを計算する。\r
+ v1=i_vertex[0].x;\r
+ v2=i_vertex[1].x;\r
+ v4=i_vertex[3].x;\r
+ \r
+ o_cparam[0]=invmat.m00*v1+invmat.m01*v2+invmat.m02*i_vertex[2].x+invmat.m03*v4;\r
+ o_cparam[1]=invmat.m10*v1+invmat.m11*v2;//m12,m13は0;\r
+ o_cparam[2]=invmat.m20*v1+invmat.m23*v4;//m21,m22は0;\r
+ o_cparam[3]=v1;//m30は1.0で、m31,m32,m33は0\r
+ \r
+ v1=i_vertex[0].y;\r
+ v2=i_vertex[1].y;\r
+ v4=i_vertex[3].y;\r
+\r
+ o_cparam[4]=invmat.m00*v1+invmat.m01*v2+invmat.m02*i_vertex[2].y+invmat.m03*v4;\r
+ o_cparam[5]=invmat.m10*v1+invmat.m11*v2;//m12,m13は0;\r
+ o_cparam[6]=invmat.m20*v1+invmat.m23*v4;//m21,m22は0;\r
+ o_cparam[7]=v1;//m30は1.0で、m31,m32,m33は0\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 疑似アフィン変換の変換パラメタ\r
+ */\r
+ private double[] _convparam=new double[8];\r
+ \r
+ /**\r
+ * @see INyARColorPatt#pickFromRaster\r
+ */\r
+ public boolean pickFromRaster(INyARRgbRaster image,NyARIntPoint2d[] i_vertexs)throws NyARException\r
+ {\r
+ final double[] conv_param=this._convparam;\r
+ int rx2,ry2;\r
+ rx2=this._size.w;\r
+ ry2=this._size.h;\r
+ int[] rgb_tmp=new int[3];\r
+\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ // 変形先領域の頂点を取得\r
+\r
+ //変換行列から現在の座標系への変換パラメタを作成\r
+ calcPara(i_vertexs,conv_param);// 変換パラメータを求める\r
+ for(int y=0;y<ry2;y++){\r
+ for(int x=0;x<rx2;x++){\r
+ final int ttx=(int)((conv_param[0]*x*y+conv_param[1]*x+conv_param[2]*y+conv_param[3])+0.5);\r
+ final int tty=(int)((conv_param[4]*x*y+conv_param[5]*x+conv_param[6]*y+conv_param[7])+0.5);\r
+ reader.getPixel((int)ttx,(int)tty,rgb_tmp);\r
+ this._patdata[x+y*rx2]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|rgb_tmp[2]; \r
+ }\r
+ }\r
+ return true;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+public interface INyARRaster\r
+{\r
+ public int getWidth();\r
+\r
+ public int getHeight();\r
+\r
+ public NyARIntSize getSize();\r
+ public INyARBufferReader getBufferReader();\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public class NyARBinRaster extends NyARRaster_BasicClass\r
+{\r
+ private INyARBufferReader _buffer_reader;\r
+ protected int[] _ref_buf;\r
+\r
+ public NyARBinRaster(int i_width, int i_height)\r
+ {\r
+ super(new NyARIntSize(i_width,i_height));\r
+ this._ref_buf = new int[i_height*i_width];\r
+ this._buffer_reader=new NyARBufferReader(this._ref_buf,INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8);\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buffer_reader;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.NyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public final class NyARGrayscaleRaster extends NyARRaster_BasicClass\r
+{\r
+\r
+ protected int[] _ref_buf;\r
+ private INyARBufferReader _buffer_reader;\r
+ \r
+ public NyARGrayscaleRaster(int i_width, int i_height)\r
+ {\r
+ super(new NyARIntSize(i_width,i_height));\r
+ this._ref_buf = new int[i_height*i_width];\r
+ this._buffer_reader=new NyARBufferReader(this._ref_buf,INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8);\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buffer_reader;\r
+ }\r
+ /**\r
+ * 4近傍の画素ベクトルを取得します。\r
+ * 0,1,0\r
+ * 1,x,1\r
+ * 0,1,0\r
+ * @param i_raster\r
+ * @param x\r
+ * @param y\r
+ * @param o_v\r
+ */\r
+ public void getPixelVector4(int x,int y,NyARIntPoint2d o_v)\r
+ {\r
+ int[] buf=this._ref_buf;\r
+ int w=this._size.w;\r
+ int idx=w*y+x;\r
+ o_v.x=buf[idx+1]-buf[idx-1];\r
+ o_v.y=buf[idx+w]-buf[idx-w];\r
+ }\r
+ /**\r
+ * 8近傍画素ベクトル\r
+ * 1,2,1\r
+ * 2,x,2\r
+ * 1,2,1\r
+ * @param i_raster\r
+ * @param x\r
+ * @param y\r
+ * @param o_v\r
+ */\r
+ public void getPixelVector8(int x,int y,NyARIntPoint2d o_v)\r
+ {\r
+ int[] buf=this._ref_buf;\r
+ NyARIntSize s=this._size;\r
+ int idx_0 =s.w*y+x;\r
+ int idx_p1=idx_0+s.w;\r
+ int idx_m1=idx_0-s.w;\r
+ int b=buf[idx_m1-1];\r
+ int d=buf[idx_m1+1];\r
+ int h=buf[idx_p1-1];\r
+ int f=buf[idx_p1+1];\r
+ o_v.x=buf[idx_0+1]-buf[idx_0-1]+(d-b+f-h)/2;\r
+ o_v.y=buf[idx_p1]-buf[idx_m1]+(f-d+h-b)/2;\r
+ }\r
+ \r
+ public void copyFrom(NyARGrayscaleRaster i_input) throws NyARException\r
+ {\r
+ int[] out_buf = (int[])this._ref_buf;\r
+ int[] in_buf = (int[]) i_input._ref_buf;\r
+ System.arraycopy(in_buf,0,out_buf,0,this._size.h*this._size.w);\r
+ return;\r
+ } \r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.NyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public final class NyARHsvRaster extends NyARRaster_BasicClass\r
+{\r
+\r
+ protected int[] _ref_buf;\r
+ private INyARBufferReader _buffer_reader;\r
+ \r
+ public NyARHsvRaster(int i_width, int i_height)\r
+ {\r
+ super(new NyARIntSize(i_width,i_height));\r
+ this._ref_buf = new int[i_height*i_width];\r
+ this._buffer_reader=new NyARBufferReader(this._ref_buf,INyARBufferReader.BUFFERFORMAT_INT1D_X7H9S8V8_32);\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buffer_reader;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**このクラスは、単機能のNyARRasterです。\r
+ * 特定タイプのバッファをラップする、INyARBufferReaderインタフェイスを提供します。\r
+ *\r
+ */\r
+public final class NyARRaster extends NyARRaster_BasicClass\r
+{\r
+ private NyARBufferReader _reader;\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._reader;\r
+ }\r
+ public NyARRaster(NyARIntSize i_size,Object i_ref_buf,int i_buf_type)\r
+ {\r
+ super(i_size);\r
+ this._reader=new NyARBufferReader(i_ref_buf,i_buf_type);\r
+ return;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public abstract class NyARRaster_BasicClass implements INyARRaster\r
+{\r
+ final protected NyARIntSize _size;\r
+ protected NyARRaster_BasicClass(final NyARIntSize i_size)\r
+ {\r
+ this._size= i_size;\r
+ }\r
+\r
+ final public int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+\r
+ final public int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+\r
+ final public NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+/**\r
+ * 8bitRGBを表現できるラスタ\r
+ * \r
+ */\r
+public interface INyARRgbRaster extends INyARRaster\r
+{\r
+ public INyARRgbPixelReader getRgbPixelReader() throws NyARException;\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public class NyARRgbRaster_BGRA extends NyARRgbRaster_BasicClass implements INyARRgbRaster\r
+{\r
+ private class PixelReader implements INyARRgbPixelReader\r
+ {\r
+ private NyARRgbRaster_BGRA _parent;\r
+\r
+ public PixelReader(NyARRgbRaster_BGRA i_parent)\r
+ {\r
+ this._parent = i_parent;\r
+ }\r
+\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+ {\r
+ final byte[] ref_buf = this._parent._ref_buf;\r
+ final int bp = (i_x + i_y * this._parent._size.w) * 4;\r
+ o_rgb[0] = (ref_buf[bp + 2] & 0xff);// R\r
+ o_rgb[1] = (ref_buf[bp + 1] & 0xff);// G\r
+ o_rgb[2] = (ref_buf[bp + 0] & 0xff);// B\r
+ return;\r
+ }\r
+\r
+ public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+ {\r
+ int bp;\r
+ final int width = _parent._size.w;\r
+ final byte[] ref_buf = _parent._ref_buf;\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ bp = (i_x[i] + i_y[i] * width) * 4;\r
+ o_rgb[i * 3 + 0] = (ref_buf[bp + 2] & 0xff);// R\r
+ o_rgb[i * 3 + 1] = (ref_buf[bp + 1] & 0xff);// G\r
+ o_rgb[i * 3 + 2] = (ref_buf[bp + 0] & 0xff);// B\r
+ }\r
+ return;\r
+ }\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+ {\r
+ final byte[] ref_buf = this._parent._ref_buf;\r
+ final int bp = (i_x + i_y * this._parent._size.w) * 4;\r
+ ref_buf[bp+0] = (byte)i_rgb[0];// R\r
+ ref_buf[bp+1] = (byte)i_rgb[1];// G\r
+ ref_buf[bp+2] = (byte)i_rgb[2];// B \r
+ }\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ \r
+ }\r
+\r
+ private INyARRgbPixelReader _rgb_reader;\r
+ private INyARBufferReader _buffer_reader;\r
+ private byte[] _ref_buf;\r
+\r
+ public static NyARRgbRaster_BGRA wrap(byte[] i_buffer, int i_width, int i_height)\r
+ {\r
+ return new NyARRgbRaster_BGRA(i_buffer, i_width, i_height);\r
+ }\r
+\r
+ private NyARRgbRaster_BGRA(byte[] i_ref_buffer, int i_width, int i_height)\r
+ {\r
+ super(new NyARIntSize(i_width,i_height));\r
+ this._ref_buf = i_ref_buffer;\r
+ this._rgb_reader = new PixelReader(this);\r
+ this._buffer_reader=new NyARBufferReader(i_ref_buffer,INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32);\r
+ return;\r
+ }\r
+ public INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._rgb_reader;\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buffer_reader;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARRgbPixelReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * NyARRasterインタフェイスの基本関数/メンバを実装したクラス\r
+ * \r
+ * \r
+ */\r
+public abstract class NyARRgbRaster_BasicClass implements INyARRgbRaster\r
+{\r
+ final protected NyARIntSize _size;\r
+ final public int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+\r
+ final public int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+\r
+ final public NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ } \r
+ protected NyARRgbRaster_BasicClass(final NyARIntSize i_size)\r
+ {\r
+ this._size= i_size;\r
+ }\r
+ public INyARRgbPixelReader getRgbPixelReader() throws NyARException\r
+ {\r
+ NyARException.notImplement();\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARRgbPixelReader;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.NyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/*\r
+ * 真っ黒の矩形を定義する。\r
+ * \r
+ */\r
+public class NyARRgbRaster_Blank extends NyARRgbRaster_BasicClass\r
+{\r
+ private class PixelReader implements INyARRgbPixelReader\r
+ {\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+ {\r
+ o_rgb[0] = 0;// R\r
+ o_rgb[1] = 0;// G\r
+ o_rgb[2] = 0;// B\r
+ return;\r
+ }\r
+\r
+ public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+ {\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ o_rgb[i * 3 + 0] = 0;// R\r
+ o_rgb[i * 3 + 1] = 0;// G\r
+ o_rgb[i * 3 + 2] = 0;// B\r
+ }\r
+ }\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ \r
+ }\r
+\r
+ private INyARRgbPixelReader _reader;\r
+ private INyARBufferReader _buffer_reader;\r
+ \r
+ public NyARRgbRaster_Blank(int i_width, int i_height)\r
+ {\r
+ super(new NyARIntSize(i_width,i_height));\r
+ this._reader = new PixelReader();\r
+ this._buffer_reader=new NyARBufferReader(null,INyARBufferReader.BUFFERFORMAT_NULL_ALLZERO);\r
+ return;\r
+ }\r
+ public INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._reader;\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buffer_reader;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.raster.rgb;\r
+\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public class NyARRgbRaster_RGB extends NyARRgbRaster_BasicClass\r
+{\r
+ protected byte[] _ref_buf;\r
+\r
+ private NyARRgbPixelReader_RGB24 _reader;\r
+ private INyARBufferReader _buffer_reader;\r
+ \r
+ public static NyARRgbRaster_RGB wrap(byte[] i_buffer, int i_width, int i_height)\r
+ {\r
+ return new NyARRgbRaster_RGB(i_buffer, i_width, i_height);\r
+ }\r
+\r
+ private NyARRgbRaster_RGB(byte[] i_ref_buffer, int i_width, int i_height)\r
+ {\r
+ super(new NyARIntSize(i_width,i_height));\r
+ this._ref_buf = i_ref_buffer;\r
+ this._reader = new NyARRgbPixelReader_RGB24(i_ref_buffer, this._size);\r
+ this._buffer_reader=new NyARBufferReader(i_ref_buffer,INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24);\r
+ return;\r
+ }\r
+ public INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._reader;\r
+ }\r
+ public INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buffer_reader;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+\r
+public interface INyARRasterFilter\r
+{\r
+ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException;\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * 色調テーブルを使用したフィルターです。\r
+ * 色調テーブルクラスのベースクラスです。\r
+ */\r
+public class NyARRasterFilter_CustomToneTable implements INyARRasterFilter\r
+{\r
+ protected final int[] table=new int[256];\r
+ private IdoFilterImpl _dofilterimpl;\r
+ protected NyARRasterFilter_CustomToneTable(int i_raster_type) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8:\r
+ this._dofilterimpl=new IdoFilterImpl_INT1D_GRAY_8();\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ this._dofilterimpl._table_ref=this.table;\r
+ }\r
+ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+ {\r
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+ this._dofilterimpl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize());\r
+ }\r
+ \r
+ private abstract class IdoFilterImpl\r
+ {\r
+ public int[] _table_ref;\r
+ public abstract void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException;\r
+ \r
+ }\r
+ private class IdoFilterImpl_INT1D_GRAY_8 extends IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException\r
+ {\r
+ assert( i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ \r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ int[] in_buf = (int[]) i_input.getBuffer();\r
+ for(int i=i_size.h*i_size.w-1;i>=0;i--)\r
+ {\r
+ out_buf[i]=this._table_ref[in_buf[i]];\r
+ }\r
+ return;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.analyzer.raster.NyARRasterAnalyzer_Histgram;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.types.NyARHistgram;\r
+/**\r
+ * ヒストグラムを平滑化します。\r
+ *\r
+ */\r
+public class NyARRasterFilter_EqualizeHist extends NyARRasterFilter_CustomToneTable\r
+{\r
+ private NyARRasterAnalyzer_Histgram _hist_analyzer;\r
+ private NyARHistgram _histgram=new NyARHistgram(256);\r
+ public NyARRasterFilter_EqualizeHist(int i_raster_type,int i_sample_interval) throws NyARException\r
+ {\r
+ super(i_raster_type);\r
+ this._hist_analyzer=new NyARRasterAnalyzer_Histgram(i_raster_type,i_sample_interval);\r
+ }\r
+ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+ {\r
+ assert (i_input!=i_output);\r
+ //ヒストグラムを得る\r
+ NyARHistgram hist=this._histgram;\r
+ this._hist_analyzer.analyzeRaster(i_input,hist);\r
+ //変換テーブルを作成\r
+ int hist_total=this._histgram.total_of_data;\r
+ int min=hist.getMinData();\r
+ int hist_size=this._histgram.length;\r
+ int sum=0;\r
+ for(int i=0;i<hist_size;i++){\r
+ sum+=hist.data[i];\r
+ this.table[i]=(int)((sum-min)*(hist_size-1)/((hist_total-min)));\r
+ }\r
+ //変換\r
+ super.doFilter(i_input, i_output);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+\r
+/**\r
+ * 平滑化フィルタ\r
+ * Gaussianフィルタで画像を平滑化します。\r
+ * カーネルサイズは3x3です。\r
+ */\r
+public class NyARRasterFilter_GaussianSmooth implements INyARRasterFilter\r
+{\r
+ private IdoFilterImpl _do_filter_impl; \r
+ public NyARRasterFilter_GaussianSmooth(int i_raster_type) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8:\r
+ this._do_filter_impl=new IdoFilterImpl_GRAY_8();\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+ {\r
+ assert (i_input!=i_output);\r
+ this._do_filter_impl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize());\r
+ }\r
+ \r
+ interface IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException;\r
+ }\r
+ class IdoFilterImpl_GRAY_8 implements IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException\r
+ {\r
+ assert (i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ assert (i_output.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ int[] in_ptr =(int[])i_input.getBuffer();\r
+ int[] out_ptr=(int[])i_output.getBuffer();\r
+ int width=i_size.w;\r
+ int height=i_size.h;\r
+ int col0,col1,col2;\r
+ int bptr=0;\r
+ //1行目\r
+ col1=in_ptr[bptr ]*2+in_ptr[bptr+width ];\r
+ col2=in_ptr[bptr+1]*2+in_ptr[bptr+width+1];\r
+ out_ptr[bptr]=(col1*2+col2)/9;\r
+ bptr++;\r
+ for(int x=0;x<width-2;x++){\r
+ col0=col1;\r
+ col1=col2;\r
+ col2=in_ptr[bptr+1]*2+in_ptr[bptr+width+1];\r
+ out_ptr[bptr]=(col0+col1*2+col2)/12;\r
+ bptr++;\r
+ } \r
+ out_ptr[bptr]=(col1+col2)/9;\r
+ bptr++;\r
+ //2行目-末行-1\r
+\r
+ for(int y=0;y<height-2;y++){\r
+ //左端\r
+ col1=in_ptr[bptr ]*2+in_ptr[bptr-width ]+in_ptr[bptr+width ];\r
+ col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1]+in_ptr[bptr+width+1];\r
+ out_ptr[bptr]=(col1+col2)/12;\r
+ bptr++;\r
+ for(int x=0;x<width-2;x++){\r
+ col0=col1;\r
+ col1=col2;\r
+ col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1]+in_ptr[bptr+width+1];\r
+ out_ptr[bptr]=(col0+col1*2+col2)/16;\r
+ bptr++;\r
+ }\r
+ //右端\r
+ out_ptr[bptr]=(col1*2+col2)/12;\r
+ bptr++;\r
+ }\r
+ //末行目\r
+ col1=in_ptr[bptr ]*2+in_ptr[bptr-width ];\r
+ col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1];\r
+ out_ptr[bptr]=(col1+col2)/9;\r
+ bptr++;\r
+ for(int x=0;x<width-2;x++){\r
+ col0=col1;\r
+ col1=col2;\r
+ col2=in_ptr[bptr+1]*2+in_ptr[bptr-width+1];\r
+ out_ptr[bptr]=(col0+col1*2+col2)/12;\r
+ bptr++;\r
+ } \r
+ out_ptr[bptr]=(col1*2+col2)/9;\r
+ bptr++;\r
+ return;\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+\r
+\r
+/**\r
+ * ネガポジ反転フィルタ。\r
+ * 画像の明暗を反転します。\r
+ *\r
+ */\r
+public class NyARRasterFilter_Reverse implements INyARRasterFilter\r
+{\r
+ private IdoFilterImpl _do_filter_impl; \r
+ public NyARRasterFilter_Reverse(int i_raster_type) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8:\r
+ this._do_filter_impl=new IdoFilterImpl_GRAY_8();\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+ {\r
+ this._do_filter_impl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize());\r
+ }\r
+ \r
+ interface IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException;\r
+ }\r
+ class IdoFilterImpl_GRAY_8 implements IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException\r
+ {\r
+ assert (i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ assert (i_output.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ int[] in_ptr =(int[])i_input.getBuffer();\r
+ int[] out_ptr=(int[])i_output.getBuffer();\r
+\r
+ \r
+ int number_of_pixel=i_size.h*i_size.w;\r
+ for(int i=0;i<number_of_pixel;i++){\r
+ out_ptr[i]=255-in_ptr[i];\r
+ }\r
+ return;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * RGB画像をHSV画像に変換します。\r
+ *\r
+ */\r
+public class NyARRasterFilter_Rgb2Hsv implements INyARRasterFilter\r
+{\r
+ private IdoFilterImpl _dofilterimpl;\r
+ public NyARRasterFilter_Rgb2Hsv(int i_raster_type) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ this._dofilterimpl=new IdoFilterImpl_BYTE1D_B8G8R8_24();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+ {\r
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+ this._dofilterimpl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize());\r
+ }\r
+ \r
+ abstract class IdoFilterImpl\r
+ {\r
+ public abstract void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException;\r
+ \r
+ }\r
+ class IdoFilterImpl_BYTE1D_B8G8R8_24 extends IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException\r
+ {\r
+ assert( i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_X7H9S8V8_32));\r
+ \r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ byte[] in_buf = (byte[]) i_input.getBuffer();\r
+ int s;\r
+ for(int i=i_size.h*i_size.w-1;i>=0;i--)\r
+ {\r
+ int r=(in_buf[i*3+2] & 0xff);\r
+ int g=(in_buf[i*3+1] & 0xff);\r
+ int b=(in_buf[i*3+0] & 0xff);\r
+ int cmax,cmin;\r
+ //最大値と最小値を計算\r
+ if(r>g){\r
+ cmax=r;\r
+ cmin=g;\r
+ }else{\r
+ cmax=g;\r
+ cmin=r;\r
+ }\r
+ if(b>cmax){\r
+ cmax=b;\r
+ }\r
+ if(b<cmin){\r
+ cmin=b;\r
+ }\r
+ int h;\r
+ if(cmax==0) {\r
+ s=0;\r
+ h=0;\r
+ }else {\r
+ s=(cmax-cmin)*255/cmax;\r
+ int cdes=cmax-cmin;\r
+ //H成分を計算\r
+ if(cdes!=0){\r
+ if(cmax==r){\r
+ h=(g-b)*60/cdes;\r
+ }else if(cmax==g){\r
+ h=(b-r)*60/cdes+2*60;\r
+ }else{\r
+ h=(r-g)*60/cdes+4*60;\r
+ }\r
+ }else{\r
+ h=0;\r
+ }\r
+ }\r
+ if(h<0)\r
+ {\r
+ h+=360;\r
+ }\r
+ //hsv変換(h9s8v8)\r
+ out_buf[i]=(0x1ff0000&(h<<16))|(0x00ff00&(s<<8))|(cmax&0xff);\r
+ }\r
+ return;\r
+ }\r
+ } \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * Roberts法で勾配を計算します。\r
+ * 出力画像のピクセルは、X,Y軸方向に-1され、下端、右端の画素は無効な値が入ります。\r
+ * X=|-1, 0| Y=|0,-1|\r
+ * | 0, 1| |1, 0|\r
+ * V=sqrt(X^2+Y+2)/2\r
+ */\r
+public class NyARRasterFilter_Roberts implements INyARRasterFilter\r
+{\r
+ private IdoFilterImpl _do_filter_impl; \r
+ public NyARRasterFilter_Roberts(int i_raster_type) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8:\r
+ this._do_filter_impl=new IdoFilterImpl_GRAY_8();\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+ {\r
+ this._do_filter_impl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize());\r
+ }\r
+ \r
+ interface IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException;\r
+ }\r
+ class IdoFilterImpl_GRAY_8 implements IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException\r
+ {\r
+ assert (i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ assert (i_output.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ int[] in_ptr =(int[])i_input.getBuffer();\r
+ int[] out_ptr=(int[])i_output.getBuffer();\r
+ int width=i_size.w;\r
+ int height=i_size.h;\r
+ for(int y=0;y<height-1;y++){\r
+ int idx=y*width;\r
+ int p00=in_ptr[idx];\r
+ int p10=in_ptr[width+idx];\r
+ int p01,p11;\r
+ for(int x=0;x<width-1;x++){\r
+ p01=in_ptr[idx+1];\r
+ p11=in_ptr[idx+width+1];\r
+ int fx=p11-p00;\r
+ int fy=p10-p01;\r
+ out_ptr[idx]=(int)Math.sqrt(fx*fx+fy*fy)>>1;\r
+ p00=p01;\r
+ p10=p11;\r
+ idx++;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ }\r
+}\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+\r
+/**\r
+ * 平滑化フィルタ\r
+ * 画像を平滑化します。\r
+ * カーネルサイズは3x3です。\r
+ */\r
+public class NyARRasterFilter_SimpleSmooth implements INyARRasterFilter\r
+{\r
+ private IdoFilterImpl _do_filter_impl; \r
+ public NyARRasterFilter_SimpleSmooth(int i_raster_type) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8:\r
+ this._do_filter_impl=new IdoFilterImpl_GRAY_8();\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ public void doFilter(INyARRaster i_input, INyARRaster i_output) throws NyARException\r
+ {\r
+ assert (i_input!=i_output);\r
+ this._do_filter_impl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize());\r
+ }\r
+ \r
+ interface IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException;\r
+ }\r
+ class IdoFilterImpl_GRAY_8 implements IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException\r
+ {\r
+ assert (i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ assert (i_output.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8));\r
+ int[] in_ptr =(int[])i_input.getBuffer();\r
+ int[] out_ptr=(int[])i_output.getBuffer();\r
+ /* 画像端は捨てる。\r
+ */\r
+ int width=i_size.w;\r
+ int height=i_size.h;\r
+ int col0,col1,col2;\r
+ int bptr=0;\r
+ //1行目\r
+ col1=in_ptr[bptr ]+in_ptr[bptr+width ];\r
+ col2=in_ptr[bptr+1]+in_ptr[bptr+width+1];\r
+ out_ptr[bptr]=(col1+col2)/4;\r
+ bptr++;\r
+ for(int x=0;x<width-2;x++){\r
+ col0=col1;\r
+ col1=col2;\r
+ col2=in_ptr[bptr+1]+in_ptr[bptr+width+1];\r
+ out_ptr[bptr]=(col0+col1+col2)/6;\r
+ bptr++;\r
+ } \r
+ out_ptr[bptr]=(col1+col2)/4;\r
+ bptr++;\r
+ //2行目-末行-1\r
+\r
+ for(int y=0;y<height-2;y++){\r
+ //左端\r
+ col1=in_ptr[bptr ]+in_ptr[bptr-width ]+in_ptr[bptr+width ];\r
+ col2=in_ptr[bptr+1]+in_ptr[bptr-width+1]+in_ptr[bptr+width+1];\r
+ out_ptr[bptr]=(col1+col2)/6;\r
+ bptr++;\r
+ for(int x=0;x<width-2;x++){\r
+ col0=col1;\r
+ col1=col2;\r
+ col2=in_ptr[bptr+1]+in_ptr[bptr-width+1]+in_ptr[bptr+width+1];\r
+ out_ptr[bptr]=(col0+col1+col2)/9;\r
+ bptr++;\r
+ }\r
+ //右端\r
+ out_ptr[bptr]=(col1+col2)/6;\r
+ bptr++;\r
+ }\r
+ //末行目\r
+ col1=in_ptr[bptr ]+in_ptr[bptr-width ];\r
+ col2=in_ptr[bptr+1]+in_ptr[bptr-width+1];\r
+ out_ptr[bptr]=(col1+col2)/4;\r
+ bptr++;\r
+ for(int x=0;x<width-2;x++){\r
+ col0=col1;\r
+ col1=col2;\r
+ col2=in_ptr[bptr+1]+in_ptr[bptr-width+1];\r
+ out_ptr[bptr]=(col0+col1+col2)/6;\r
+ bptr++;\r
+ } \r
+ out_ptr[bptr]=(col1+col2)/4;\r
+ bptr++;\r
+ return;\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * 色調テーブルを使用したフィルターです。\r
+ * 基本的な関数テーブルで色調テーブルを作成できます。\r
+ */\r
+public class NyARRasterFilter_ToneTable extends NyARRasterFilter_CustomToneTable\r
+{\r
+ public NyARRasterFilter_ToneTable(int i_raster_type) throws NyARException\r
+ {\r
+ super(i_raster_type);\r
+ }\r
+ /**\r
+ * 点x,yを通過する、傾きi_aの直線をテーブルに書き込みます。\r
+ * @param i_x\r
+ * @param i_y\r
+ * @param i_a\r
+ */\r
+ public void setLine(int i_x,int i_y,double i_a)\r
+ {\r
+ if(i_a==0){\r
+ int i;\r
+ for(i=0;i<=i_x;i++){\r
+ this.table[i]=0;\r
+ }\r
+ for(i=0;i<256;i++){\r
+ this.table[i]=255;\r
+ }\r
+ }else{\r
+ int b=i_y-(int)(i_a*i_x);\r
+ for(int i=0;i<256;i++){\r
+ int v=(int)(i_a*i)+b;\r
+ this.table[i]=v<0?0:v>255?255:v;\r
+ }\r
+ }\r
+ }\r
+ /**\r
+ * 点0,0を通過する、傾きaの直線をテーブルに書き込みます。\r
+ * i_aの値をvとしたとき、以下のようになります。\r
+ * v<=0 黒色\r
+ * 0<v<1 暗くする。\r
+ * v=0 変化しない\r
+ * 1<v<255 明るくする。\r
+ * 255<=v 白色\r
+ * @param i_ax\r
+ * @param i_ay\r
+ */\r
+ public void setLine(double i_a)\r
+ {\r
+ setLine(0,0,i_a);\r
+ }\r
+ /**\r
+ * 点 i_x,i_yを中心とする、ゲインi_gainのシグモイド関数をテーブルに書き込みます。\r
+ * @param i_x\r
+ * @param i_y\r
+ * @param i_gain\r
+ */\r
+ public void setSigmoid(int i_x,int i_y,double i_gain)\r
+ {\r
+ for(int i=0;i<256;i++){\r
+ int v=255*(int)(1/(1+Math.exp(i_gain*(i-i_x)))-0.5)+i_y;\r
+ this.table[i]=v<0?0:v>255?255:v;\r
+ }\r
+ }\r
+ /**\r
+ * ガンマ補正値をテーブルに書き込みます。\r
+ * @param i_gamma\r
+ */\r
+ public void setGamma(double i_gamma)\r
+ {\r
+ for(int i=0;i<256;i++){\r
+ this.table[i]=(int)(Math.pow((double)i/255.0,i_gamma)*255.0);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARGrayscaleRaster;\r
+\r
+public interface INyARRasterFilter_Gs2Bin\r
+{\r
+ public abstract void doFilter(NyARGrayscaleRaster i_input, NyARBinRaster i_output) throws NyARException;\r
+\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARGrayscaleRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public class NyARRasterFilter_ConstantThrshold implements INyARRasterFilter_Gs2Bin\r
+{\r
+ public int _threshold;\r
+ public NyARRasterFilter_ConstantThrshold(int i_initial_threshold) throws NyARException\r
+ {\r
+ //初期化\r
+ this._threshold=i_initial_threshold;\r
+ }\r
+ /**\r
+ * 2値化の閾値を設定する。\r
+ * 暗点<=th<明点となります。\r
+ * @throws NyARException\r
+ */\r
+ public NyARRasterFilter_ConstantThrshold() throws NyARException\r
+ {\r
+ this._threshold=0;\r
+ }\r
+\r
+ \r
+ public void setThreshold(int i_threshold)\r
+ {\r
+ this._threshold = i_threshold;\r
+ }\r
+ public void doFilter(NyARGrayscaleRaster i_input, NyARBinRaster i_output) throws NyARException\r
+ {\r
+ INyARBufferReader in_buffer_reader=i_input.getBufferReader(); \r
+ INyARBufferReader out_buffer_reader=i_output.getBufferReader();\r
+ int[] out_buf = (int[]) out_buffer_reader.getBuffer();\r
+ int[] in_buf = (int[]) in_buffer_reader.getBuffer();\r
+ NyARIntSize s=i_input.getSize();\r
+ \r
+ final int th=this._threshold;\r
+ int bp =s.w*s.h-1;\r
+ final int pix_count =s.h*s.w;\r
+ final int pix_mod_part=pix_count-(pix_count%8);\r
+ for(bp=pix_count-1;bp>=pix_mod_part;bp--){\r
+ out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+ }\r
+ //タイリング\r
+ for (;bp>=0;) {\r
+ out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+ bp--;\r
+ out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+ bp--;\r
+ out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+ bp--;\r
+ out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+ bp--;\r
+ out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+ bp--;\r
+ out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+ bp--;\r
+ out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+ bp--;\r
+ out_buf[bp]=(in_buf[bp] & 0xff)<=th?0:1;\r
+ bp--;\r
+ }\r
+ return; \r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+\r
+public interface INyARRasterFilter_RgbToBin\r
+{\r
+ public void doFilter(INyARRgbRaster i_input, NyARBinRaster i_output) throws NyARException;\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+\r
+\r
+/**\r
+ * 定数閾値による2値化をする。\r
+ * \r
+ */\r
+public class NyARRasterFilter_ARToolkitThreshold implements INyARRasterFilter_RgbToBin\r
+{\r
+ private int _threshold;\r
+ private IdoThFilterImpl _do_threshold_impl;\r
+\r
+ public NyARRasterFilter_ARToolkitThreshold(int i_threshold,int i_input_raster_type) throws NyARException\r
+ {\r
+ this._threshold = i_threshold;\r
+ switch (i_input_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ this._do_threshold_impl=new doThFilterImpl_BUFFERFORMAT_BYTE1D_RGB_24();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32:\r
+ this._do_threshold_impl=new doThFilterImpl_BUFFERFORMAT_BYTE1D_B8G8R8X8_32();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_X8R8G8B8_32:\r
+ this._do_threshold_impl=new doThFilterImpl_BUFFERFORMAT_BYTE1D_X8R8G8B8_32();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32:\r
+ this._do_threshold_impl=new doThFilterImpl_BUFFERFORMAT_INT1D_X8R8G8B8_32();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_WORD1D_R5G6B5_16LE:\r
+ this._do_threshold_impl=new doThFilterImpl_BUFFERFORMAT_WORD1D_R5G6B5_16LE();\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+\r
+ \r
+ }\r
+ /**\r
+ * 画像を2値化するための閾値。暗点<=th<明点となります。\r
+ * @param i_threshold\r
+ */\r
+ public void setThreshold(int i_threshold)\r
+ {\r
+ this._threshold = i_threshold;\r
+ }\r
+\r
+ public void doFilter(INyARRgbRaster i_input, NyARBinRaster i_output) throws NyARException\r
+ {\r
+ INyARBufferReader in_buffer_reader=i_input.getBufferReader(); \r
+ INyARBufferReader out_buffer_reader=i_output.getBufferReader();\r
+\r
+ assert (out_buffer_reader.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8));\r
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+ this._do_threshold_impl.doThFilter(in_buffer_reader,out_buffer_reader,i_output.getSize(), this._threshold);\r
+ return;\r
+ }\r
+ /*\r
+ * ここから各ラスタ用のフィルタ実装\r
+ */\r
+ interface IdoThFilterImpl\r
+ {\r
+ public void doThFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size,int i_threshold);\r
+ }\r
+ class doThFilterImpl_BUFFERFORMAT_BYTE1D_RGB_24 implements IdoThFilterImpl\r
+ {\r
+ public void doThFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size,int i_threshold)\r
+ {\r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ byte[] in_buf = (byte[]) i_input.getBuffer();\r
+ \r
+ final int th=i_threshold*3;\r
+ int bp =(i_size.w*i_size.h-1)*3;\r
+ int w;\r
+ int xy;\r
+ final int pix_count =i_size.h*i_size.w;\r
+ final int pix_mod_part=pix_count-(pix_count%8);\r
+ for(xy=pix_count-1;xy>=pix_mod_part;xy--){\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 3;\r
+ }\r
+ //タイリング\r
+ for (;xy>=0;) {\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 3;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 3;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 3;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 3;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 3;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 3;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 3;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 3;\r
+ xy--;\r
+ }\r
+ return; \r
+ }\r
+ \r
+ }\r
+ class doThFilterImpl_BUFFERFORMAT_BYTE1D_B8G8R8X8_32 implements IdoThFilterImpl\r
+ {\r
+ public void doThFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size,int i_threshold)\r
+ {\r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ byte[] in_buf = (byte[]) i_input.getBuffer();\r
+ \r
+ final int th=i_threshold*3;\r
+ int bp =(i_size.w*i_size.h-1)*4;\r
+ int w;\r
+ int xy;\r
+ final int pix_count =i_size.h*i_size.w;\r
+ final int pix_mod_part=pix_count-(pix_count%8);\r
+ for(xy=pix_count-1;xy>=pix_mod_part;xy--){\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ }\r
+ //タイリング\r
+ for (;xy>=0;) {\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ } \r
+ } \r
+ }\r
+ \r
+ class doThFilterImpl_BUFFERFORMAT_BYTE1D_X8R8G8B8_32 implements IdoThFilterImpl\r
+ {\r
+ public void doThFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size,int i_threshold)\r
+ {\r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ byte[] in_buf = (byte[]) i_input.getBuffer();\r
+ \r
+ final int th=i_threshold*3;\r
+ int bp =(i_size.w*i_size.h-1)*4;\r
+ int w;\r
+ int xy;\r
+ final int pix_count =i_size.h*i_size.w;\r
+ final int pix_mod_part=pix_count-(pix_count%8);\r
+ for(xy=pix_count-1;xy>=pix_mod_part;xy--){\r
+ w= ((in_buf[bp+1] & 0xff) + (in_buf[bp + 2] & 0xff) + (in_buf[bp + 3] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ }\r
+ //タイリング\r
+ for (;xy>=0;) {\r
+ w= ((in_buf[bp+1] & 0xff) + (in_buf[bp + 2] & 0xff) + (in_buf[bp + 3] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp+1] & 0xff) + (in_buf[bp + 2] & 0xff) + (in_buf[bp + 3] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp+1] & 0xff) + (in_buf[bp + 2] & 0xff) + (in_buf[bp + 3] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp+1] & 0xff) + (in_buf[bp + 2] & 0xff) + (in_buf[bp + 3] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp+1] & 0xff) + (in_buf[bp + 2] & 0xff) + (in_buf[bp + 3] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp+1] & 0xff) + (in_buf[bp + 2] & 0xff) + (in_buf[bp + 3] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp+1] & 0xff) + (in_buf[bp + 2] & 0xff) + (in_buf[bp + 3] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ w= ((in_buf[bp+1] & 0xff) + (in_buf[bp + 2] & 0xff) + (in_buf[bp + 3] & 0xff));\r
+ out_buf[xy]=w<=th?0:1;\r
+ bp -= 4;\r
+ xy--;\r
+ }\r
+ return; \r
+ }\r
+ \r
+ } \r
+ \r
+ class doThFilterImpl_BUFFERFORMAT_INT1D_X8R8G8B8_32 implements IdoThFilterImpl\r
+ {\r
+ public void doThFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size,int i_threshold)\r
+ {\r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ int[] in_buf = (int[]) i_input.getBuffer();\r
+ \r
+ final int th=i_threshold*3;\r
+ int w;\r
+ int xy;\r
+ final int pix_count =i_size.h*i_size.w;\r
+ final int pix_mod_part=pix_count-(pix_count%8);\r
+\r
+ for(xy=pix_count-1;xy>=pix_mod_part;xy--){\r
+ w=in_buf[xy];\r
+ out_buf[xy]=(((w>>16)&0xff)+((w>>8)&0xff)+(w&0xff))<=th?0:1;\r
+ }\r
+ //タイリング\r
+ for (;xy>=0;) {\r
+ w=in_buf[xy];\r
+ out_buf[xy]=(((w>>16)&0xff)+((w>>8)&0xff)+(w&0xff))<=th?0:1;\r
+ xy--;\r
+ w=in_buf[xy];\r
+ out_buf[xy]=(((w>>16)&0xff)+((w>>8)&0xff)+(w&0xff))<=th?0:1;\r
+ xy--;\r
+ w=in_buf[xy];\r
+ out_buf[xy]=(((w>>16)&0xff)+((w>>8)&0xff)+(w&0xff))<=th?0:1;\r
+ xy--;\r
+ w=in_buf[xy];\r
+ out_buf[xy]=(((w>>16)&0xff)+((w>>8)&0xff)+(w&0xff))<=th?0:1;\r
+ xy--;\r
+ w=in_buf[xy];\r
+ out_buf[xy]=(((w>>16)&0xff)+((w>>8)&0xff)+(w&0xff))<=th?0:1;\r
+ xy--;\r
+ w=in_buf[xy];\r
+ out_buf[xy]=(((w>>16)&0xff)+((w>>8)&0xff)+(w&0xff))<=th?0:1;\r
+ xy--;\r
+ w=in_buf[xy];\r
+ out_buf[xy]=(((w>>16)&0xff)+((w>>8)&0xff)+(w&0xff))<=th?0:1;\r
+ xy--;\r
+ w=in_buf[xy];\r
+ out_buf[xy]=(((w>>16)&0xff)+((w>>8)&0xff)+(w&0xff))<=th?0:1;\r
+ xy--;\r
+ } \r
+ } \r
+ }\r
+ \r
+ class doThFilterImpl_BUFFERFORMAT_WORD1D_R5G6B5_16LE implements IdoThFilterImpl\r
+ {\r
+ public void doThFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size,int i_threshold)\r
+ {\r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ short[] in_buf = (short[]) i_input.getBuffer();\r
+ \r
+ final int th=i_threshold*3;\r
+ int w;\r
+ int xy;\r
+ final int pix_count =i_size.h*i_size.w;\r
+ final int pix_mod_part=pix_count-(pix_count%8);\r
+\r
+ for(xy=pix_count-1;xy>=pix_mod_part;xy--){ \r
+ w =(int)in_buf[xy];\r
+ w = ((w & 0xf800) >> 8) + ((w & 0x07e0) >> 3) + ((w & 0x001f) << 3);\r
+ out_buf[xy] = w <= th ? 0 : 1;\r
+ }\r
+ //タイリング\r
+ for (;xy>=0;) {\r
+ w =(int)in_buf[xy];\r
+ w = ((w & 0xf800) >> 8) + ((w & 0x07e0) >> 3) + ((w & 0x001f) << 3);\r
+ out_buf[xy] = w <= th ? 0 : 1;\r
+ xy--;\r
+ w =(int)in_buf[xy];\r
+ w = ((w & 0xf800) >> 8) + ((w & 0x07e0) >> 3) + ((w & 0x001f) << 3);\r
+ out_buf[xy] = w <= th ? 0 : 1;\r
+ xy--;\r
+ w =(int)in_buf[xy];\r
+ w = ((w & 0xf800) >> 8) + ((w & 0x07e0) >> 3) + ((w & 0x001f) << 3);\r
+ out_buf[xy] = w <= th ? 0 : 1;\r
+ xy--;\r
+ w =(int)in_buf[xy];\r
+ w = ((w & 0xf800) >> 8) + ((w & 0x07e0) >> 3) + ((w & 0x001f) << 3);\r
+ out_buf[xy] = w <= th ? 0 : 1;\r
+ xy--;\r
+ w =(int)in_buf[xy];\r
+ w = ((w & 0xf800) >> 8) + ((w & 0x07e0) >> 3) + ((w & 0x001f) << 3);\r
+ out_buf[xy] = w <= th ? 0 : 1;\r
+ xy--;\r
+ w =(int)in_buf[xy];\r
+ w = ((w & 0xf800) >> 8) + ((w & 0x07e0) >> 3) + ((w & 0x001f) << 3);\r
+ out_buf[xy] = w <= th ? 0 : 1;\r
+ xy--;\r
+ w =(int)in_buf[xy];\r
+ w = ((w & 0xf800) >> 8) + ((w & 0x07e0) >> 3) + ((w & 0x001f) << 3);\r
+ out_buf[xy] = w <= th ? 0 : 1;\r
+ xy--;\r
+ w =(int)in_buf[xy];\r
+ w = ((w & 0xf800) >> 8) + ((w & 0x07e0) >> 3) + ((w & 0x001f) << 3);\r
+ out_buf[xy] = w <= th ? 0 : 1;\r
+ xy--;\r
+ }\r
+ } \r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+\r
+/**\r
+ * このインタフェイスは、RGBラスタをグレースケールラスタに変換します。\r
+ *\r
+ */\r
+public interface INyARRasterFilter_RgbToGs\r
+{\r
+ public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException;\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * RGBラスタをGrayScaleに変換するフィルタを作成します。\r
+ * このフィルタは、RGB値の平均値を、(R+G+B)/3で算出します。\r
+ *\r
+ */\r
+public class NyARRasterFilter_Rgb2Gs_AveAdd implements INyARRasterFilter_RgbToGs\r
+{\r
+ IdoThFilterImpl _do_filter_impl;\r
+ public NyARRasterFilter_Rgb2Gs_AveAdd(int i_raster_type) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ this._do_filter_impl=new doThFilterImpl_BYTE1D_B8G8R8_24();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8X8_32:\r
+ this._do_filter_impl=new doThFilterImpl_BYTE1D_B8G8R8X8_32();\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException\r
+ {\r
+ INyARBufferReader in_buffer_reader=i_input.getBufferReader(); \r
+ INyARBufferReader out_buffer_reader=i_output.getBufferReader(); \r
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+ this._do_filter_impl.doFilter(in_buffer_reader,out_buffer_reader,i_input.getSize());\r
+ return;\r
+ }\r
+ \r
+ /*\r
+ * ここから各種ラスタ向けのフィルタ実装\r
+ *\r
+ */\r
+ interface IdoThFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size);\r
+ }\r
+ class doThFilterImpl_BYTE1D_B8G8R8_24 implements IdoThFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size)\r
+ {\r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ byte[] in_buf = (byte[]) i_input.getBuffer();\r
+ \r
+ int bp = 0;\r
+ for (int y = 0; y < i_size.h; y++) {\r
+ for (int x = 0; x < i_size.w; x++) {\r
+ out_buf[y*i_size.w+x] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3;\r
+ bp += 3;\r
+ }\r
+ }\r
+ return;\r
+ } \r
+ }\r
+ class doThFilterImpl_BYTE1D_B8G8R8X8_32 implements IdoThFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size)\r
+ {\r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ byte[] in_buf = (byte[]) i_input.getBuffer();\r
+\r
+ int bp = 0;\r
+ for (int y = 0; y < i_size.h; y++) {\r
+ for (int x = 0; x < i_size.w; x++) {\r
+ out_buf[y*i_size.w+x] = ((in_buf[bp] & 0xff) + (in_buf[bp + 1] & 0xff) + (in_buf[bp + 2] & 0xff)) / 3;\r
+ bp += 4;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ \r
+ \r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_RgbToGs;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+\r
+/**\r
+ * RGBラスタをGrayScaleに変換するフィルタを作成します。\r
+ * このフィルタは、RGB値の平均値を、(R*G*B)/(255*255)で算出します。\r
+ * \r
+ * この値は、RGB成分の作る立方体の体積を0-255スケールにした値です。\r
+ *\r
+ */\r
+public class NyARRasterFilter_Rgb2Gs_RgbCube implements INyARRasterFilter_RgbToGs\r
+{\r
+ private IdoFilterImpl _dofilterimpl;\r
+ public NyARRasterFilter_Rgb2Gs_RgbCube(int i_raster_type) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ this._dofilterimpl=new IdoFilterImpl_BYTE1D_B8G8R8_24();\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException\r
+ {\r
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+ this._dofilterimpl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize());\r
+ }\r
+ \r
+ interface IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException;\r
+ }\r
+ class IdoFilterImpl_BYTE1D_B8G8R8_24 implements IdoFilterImpl\r
+ {\r
+ /**\r
+ * This function is not optimized.\r
+ */\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException\r
+ {\r
+ assert( i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24)\r
+ || i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24));\r
+ \r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ byte[] in_buf = (byte[]) i_input.getBuffer();\r
+\r
+ int bp = 0;\r
+ for (int y = 0; y < i_size.h; y++) {\r
+ for (int x = 0; x < i_size.w; x++) {\r
+ out_buf[y*i_size.w+x] = ((in_buf[bp] & 0xff) * (in_buf[bp + 1] & 0xff) * (in_buf[bp + 2] & 0xff)) >> 16;\r
+ bp += 3;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ }\r
+ \r
+}\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARGrayscaleRaster;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2gs.INyARRasterFilter_RgbToGs;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.INyARBufferReader;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+/**\r
+ * YCbCr変換して、Y成分のグレースケールの値を計算します。\r
+ * 変換式は、http://www.tyre.gotdns.org/を参考にしました。\r
+ */\r
+public class NyARRasterFilter_Rgb2Gs_YCbCr implements INyARRasterFilter_RgbToGs\r
+{\r
+ private IdoFilterImpl _dofilterimpl;\r
+ public NyARRasterFilter_Rgb2Gs_YCbCr(int i_raster_type) throws NyARException\r
+ {\r
+ switch (i_raster_type) {\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ this._dofilterimpl=new IdoFilterImpl_BYTE1D_B8G8R8_24();\r
+ break;\r
+ case INyARBufferReader.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ public void doFilter(INyARRgbRaster i_input, NyARGrayscaleRaster i_output) throws NyARException\r
+ {\r
+ assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);\r
+ this._dofilterimpl.doFilter(i_input.getBufferReader(),i_output.getBufferReader(),i_input.getSize());\r
+ }\r
+ \r
+ interface IdoFilterImpl\r
+ {\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException;\r
+ }\r
+ class IdoFilterImpl_BYTE1D_B8G8R8_24 implements IdoFilterImpl\r
+ {\r
+ /**\r
+ * This function is not optimized.\r
+ */\r
+ public void doFilter(INyARBufferReader i_input, INyARBufferReader i_output,NyARIntSize i_size) throws NyARException\r
+ {\r
+ assert( i_input.isEqualBufferType(INyARBufferReader.BUFFERFORMAT_BYTE1D_B8G8R8_24));\r
+ \r
+ int[] out_buf = (int[]) i_output.getBuffer();\r
+ byte[] in_buf = (byte[]) i_input.getBuffer();\r
+\r
+ int bp = 0;\r
+ for (int y = 0; y < i_size.h; y++){\r
+ for (int x = 0; x < i_size.w; x++){\r
+ out_buf[y*i_size.w+x]=(306*(in_buf[bp+2] & 0xff)+601*(in_buf[bp + 1] & 0xff)+117 * (in_buf[bp + 0] & 0xff))>>10;\r
+ bp += 3;\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ } \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+/**\r
+ * このインタフェイスは、画素データを格納するバッファオブジェクト\r
+ * へのアクセス方法と、その形式を定義します。\r
+ *\r
+ */\r
+public interface INyARBufferReader\r
+{\r
+ public static final int BYTE1D =0x00010000;\r
+ public static final int INT2D =0x00020000;\r
+ public static final int SHORT1D=0x00030000;\r
+ public static final int INT1D =0x00040000;\r
+ // ID規約\r
+ // 24-31(8)予約\r
+ // 16-27(8)型ID\r
+ // 00:無効/01:byte[]/02:int[][]/03:short[]\r
+ // 08-15(8)ビットフォーマットID\r
+ // 00:24bit/01:32bit/02:16bit\r
+ // 00-07(8)型番号\r
+ //\r
+ /**\r
+ * RGB24フォーマットで、全ての画素が0\r
+ */\r
+ public static final int BUFFERFORMAT_NULL_ALLZERO = 0x00000001;\r
+\r
+ /**\r
+ * byte[]で、R8G8B8の24ビットで画素が格納されている。\r
+ */\r
+ public static final int BUFFERFORMAT_BYTE1D_R8G8B8_24 = BYTE1D|0x0001;\r
+ /**\r
+ * byte[]で、B8G8R8の24ビットで画素が格納されている。\r
+ */\r
+ public static final int BUFFERFORMAT_BYTE1D_B8G8R8_24 = BYTE1D|0x0002;\r
+ /**\r
+ * byte[]で、R8G8B8X8の32ビットで画素が格納されている。\r
+ */\r
+ public static final int BUFFERFORMAT_BYTE1D_B8G8R8X8_32 = BYTE1D|0x0101;\r
+ /**\r
+ * byte[]で、X8R8G8B8の32ビットで画素が格納されている。\r
+ */\r
+ public static final int BUFFERFORMAT_BYTE1D_X8R8G8B8_32 = BYTE1D|0x0102;\r
+\r
+ /**\r
+ * byte[]で、RGB565の16ビット(little/big endian)で画素が格納されている。\r
+ */\r
+ public static final int BUFFERFORMAT_BYTE1D_R5G6B5_16LE = BYTE1D|0x0201;\r
+ public static final int BUFFERFORMAT_BYTE1D_R5G6B5_16BE = BYTE1D|0x0202;\r
+ /**\r
+ * short[]で、RGB565の16ビット(little/big endian)で画素が格納されている。\r
+ */ \r
+ public static final int BUFFERFORMAT_WORD1D_R5G6B5_16LE = SHORT1D|0x0201;\r
+ public static final int BUFFERFORMAT_WORD1D_R5G6B5_16BE = SHORT1D|0x0202;\r
+\r
+ \r
+ /**\r
+ * int[][]で特に値範囲を定めない\r
+ */\r
+ public static final int BUFFERFORMAT_INT2D = INT2D|0x0000;\r
+ /**\r
+ * int[][]で0-255のグレイスケール画像\r
+ */\r
+ public static final int BUFFERFORMAT_INT2D_GRAY_8 = INT2D|0x0001;\r
+ /**\r
+ * int[][]で0/1の2値画像\r
+ * これは、階調値1bitのBUFFERFORMAT_INT2D_GRAY_1と同じです。\r
+ */\r
+ public static final int BUFFERFORMAT_INT2D_BIN_8 = INT2D|0x0002;\r
+\r
+ /**\r
+ * int[]で特に値範囲を定めない\r
+ */\r
+ public static final int BUFFERFORMAT_INT1D = INT1D|0x0000;\r
+ /**\r
+ * int[]で0-255のグレイスケール画像\r
+ */\r
+ public static final int BUFFERFORMAT_INT1D_GRAY_8 = INT1D|0x0001;\r
+ /**\r
+ * int[]で0/1の2値画像\r
+ * これは、階調1bitのBUFFERFORMAT_INT1D_GRAY_1と同じです。\r
+ */\r
+ public static final int BUFFERFORMAT_INT1D_BIN_8 = INT1D|0x0002;\r
+ \r
+ \r
+ /**\r
+ * int[]で、XRGB32の32ビットで画素が格納されている。\r
+ */ \r
+ public static final int BUFFERFORMAT_INT1D_X8R8G8B8_32=INT1D|0x0102;\r
+\r
+ /**\r
+ * H:9bit(0-359),S:8bit(0-255),V(0-255)\r
+ */\r
+ public static final int BUFFERFORMAT_INT1D_X7H9S8V8_32=INT1D|0x0103;\r
+ \r
+\r
+ /**\r
+ * バッファオブジェクトを返します。\r
+ * @return\r
+ */\r
+ public Object getBuffer();\r
+ /**\r
+ * バッファオブジェクトの形式を返します。\r
+ * @return\r
+ */\r
+ public int getBufferType();\r
+ /**\r
+ * バッファオブジェクトの形式が、i_type_valueにが一致するか返します。\r
+ * @param i_type_value\r
+ * @return\r
+ */\r
+ public boolean isEqualBufferType(int i_type_value);\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+/**\r
+ * R8G8B8でピクセルを読み出すインタフェイス\r
+ * \r
+ */\r
+public interface INyARRgbPixelReader\r
+{\r
+ /**\r
+ * 1ピクセルをint配列にして返します。\r
+ * \r
+ * @param i_x\r
+ * @param i_y\r
+ * @param i_rgb\r
+ */\r
+ public void getPixel(int i_x, int i_y, int[] i_rgb) throws NyARException;\r
+\r
+ /**\r
+ * 複数のピクセル値をint配列に返します。\r
+ * 配列には、[R1][G1][B1][R2][G2][B2]の順でピクセル値が格納されます。\r
+ * \r
+ * @param i_x\r
+ * xのインデックス配列\r
+ * @param i_y\r
+ * yのインデックス配列\r
+ */\r
+ public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException;\r
+ \r
+ /**\r
+ * 1ピクセルを設定します。\r
+ * @param i_x\r
+ * @param i_y\r
+ * @param i_rgb\r
+ * @throws NyARException\r
+ */\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException;\r
+ /**\r
+ * 複数のピクセル値をint配列から設定します。\r
+ * @param i_x\r
+ * @param i_y\r
+ * @param i_num\r
+ * @param i_intrgb\r
+ * @throws NyARException\r
+ */\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException;\r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+public final class NyARBufferReader implements INyARBufferReader\r
+{\r
+ private Object _buffer;\r
+ private int _buffer_type;\r
+ private NyARBufferReader()\r
+ {\r
+ return;\r
+ }\r
+ public NyARBufferReader(Object i_buffer,int i_buffer_type)\r
+ {\r
+ this._buffer=i_buffer;\r
+ this._buffer_type=i_buffer_type;\r
+ return;\r
+ }\r
+ public Object getBuffer()\r
+ {\r
+ return this._buffer;\r
+ }\r
+ public int getBufferType()\r
+ {\r
+ return _buffer_type;\r
+ }\r
+ public boolean isEqualBufferType(int i_type_value)\r
+ {\r
+ return this._buffer_type==i_type_value;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * byte[]配列に、パディング無しの8bit画素値が、XRGBXRGBの順で並んでいる\r
+ * バッファに使用できるピクセルリーダー\r
+ *\r
+ */\r
+public class NyARRgbPixelReader_BYTE1D_X8R8G8B8_32 implements INyARRgbPixelReader\r
+{\r
+ protected byte[] _ref_buf;\r
+\r
+ private NyARIntSize _size;\r
+\r
+ public NyARRgbPixelReader_BYTE1D_X8R8G8B8_32(byte[] i_buf, NyARIntSize i_size)\r
+ {\r
+ this._ref_buf = i_buf;\r
+ this._size = i_size;\r
+ }\r
+\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+ {\r
+ final byte[] ref_buf = this._ref_buf;\r
+ final int bp = (i_x + i_y * this._size.w) * 4;\r
+ o_rgb[0] = (ref_buf[bp + 1] & 0xff);// R\r
+ o_rgb[1] = (ref_buf[bp + 2] & 0xff);// G\r
+ o_rgb[2] = (ref_buf[bp + 3] & 0xff);// B\r
+ return;\r
+ }\r
+\r
+ public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+ {\r
+ int bp;\r
+ final int width = this._size.w;\r
+ final byte[] ref_buf = this._ref_buf;\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ bp = (i_x[i] + i_y[i] * width) * 4;\r
+ o_rgb[i * 3 + 0] = (ref_buf[bp + 1] & 0xff);// R\r
+ o_rgb[i * 3 + 1] = (ref_buf[bp + 2] & 0xff);// G\r
+ o_rgb[i * 3 + 2] = (ref_buf[bp + 3] & 0xff);// B\r
+ }\r
+ return;\r
+ }\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public class NyARRgbPixelReader_INT1D_GRAY_8 implements INyARRgbPixelReader\r
+{\r
+ protected int[] _ref_buf;\r
+\r
+ private NyARIntSize _size;\r
+\r
+ public NyARRgbPixelReader_INT1D_GRAY_8(int[] i_buf, NyARIntSize i_size)\r
+ {\r
+ this._ref_buf = i_buf;\r
+ this._size = i_size;\r
+ }\r
+\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+ {\r
+ o_rgb[0] = o_rgb[1]=o_rgb[2]=this._ref_buf[i_x + i_y * this._size.w];\r
+ return;\r
+ }\r
+\r
+ public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+ {\r
+ final int width = this._size.w;\r
+ final int[] ref_buf = this._ref_buf;\r
+ for (int i = i_num - 1; i >= 0; i--){\r
+ o_rgb[i * 3 + 0] = o_rgb[i * 3 + 1]=o_rgb[i * 3 + 2]=ref_buf[i_x[i] + i_y[i] * width];\r
+ }\r
+ return;\r
+ }\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+public class NyARRgbPixelReader_INT1D_X8R8G8B8_32 implements INyARRgbPixelReader\r
+{\r
+ protected int[] _ref_buf;\r
+\r
+ private NyARIntSize _size;\r
+\r
+ public NyARRgbPixelReader_INT1D_X8R8G8B8_32(int[] i_buf, NyARIntSize i_size)\r
+ {\r
+ this._ref_buf = i_buf;\r
+ this._size = i_size;\r
+ }\r
+\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+ {\r
+ final int rgb= this._ref_buf[i_x + i_y * this._size.w];\r
+ o_rgb[0] = (rgb>>16)&0xff;// R\r
+ o_rgb[1] = (rgb>>8)&0xff;// G\r
+ o_rgb[2] = rgb&0xff;// B\r
+ return;\r
+ }\r
+\r
+ public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+ {\r
+ final int width = this._size.w;\r
+ final int[] ref_buf = this._ref_buf;\r
+ for (int i = i_num - 1; i >= 0; i--){\r
+ int rgb=ref_buf[i_x[i] + i_y[i] * width];\r
+ o_rgb[i * 3 + 0] = (rgb>>16)&0xff;// R\r
+ o_rgb[i * 3 + 1] = (rgb>>8)&0xff;// G\r
+ o_rgb[i * 3 + 2] = rgb&0xff;// B\r
+ }\r
+ return;\r
+ }\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+ {\r
+ this._ref_buf[i_x + i_y * this._size.w]=((i_rgb[0]<<16)&0xff)|((i_rgb[1]<<8)&0xff)|((i_rgb[2])&0xff);\r
+ }\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.rasterreader;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * byte[]配列に、パディング無しの8bit画素値が、RGBRGBの順で並んでいる\r
+ * バッファに使用できるピクセルリーダー\r
+ *\r
+ */\r
+public class NyARRgbPixelReader_RGB24 implements INyARRgbPixelReader\r
+{\r
+ protected byte[] _ref_buf;\r
+\r
+ private NyARIntSize _size;\r
+\r
+ public NyARRgbPixelReader_RGB24(byte[] i_buf, NyARIntSize i_size)\r
+ {\r
+ this._ref_buf = i_buf;\r
+ this._size = i_size;\r
+ }\r
+\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb)\r
+ {\r
+ final byte[] ref_buf = this._ref_buf;\r
+ final int bp = (i_x + i_y * this._size.w) * 3;\r
+ o_rgb[0] = (ref_buf[bp + 0] & 0xff);// R\r
+ o_rgb[1] = (ref_buf[bp + 1] & 0xff);// G\r
+ o_rgb[2] = (ref_buf[bp + 2] & 0xff);// B\r
+ return;\r
+ }\r
+\r
+ public void getPixelSet(int[] i_x, int[] i_y, int i_num, int[] o_rgb)\r
+ {\r
+ int bp;\r
+ final int width = this._size.w;\r
+ final byte[] ref_buf = this._ref_buf;\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ bp = (i_x[i] + i_y[i] * width) * 3;\r
+ o_rgb[i * 3 + 0] = (ref_buf[bp + 0] & 0xff);// R\r
+ o_rgb[i * 3 + 1] = (ref_buf[bp + 1] & 0xff);// G\r
+ o_rgb[i * 3 + 2] = (ref_buf[bp + 2] & 0xff);// B\r
+ }\r
+ return;\r
+ }\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ \r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.*;\r
+\r
+/**\r
+ * 輪郭線を取得するクラスです。\r
+ *\r
+ */\r
+public class ContourPickup\r
+{\r
+ //巡回参照できるように、テーブルを二重化\r
+ // 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6\r
+ protected final static int[] _getContour_xdir = { 0, 1, 1, 1, 0,-1,-1,-1 , 0, 1, 1, 1, 0,-1,-1};\r
+ protected final static int[] _getContour_ydir = {-1,-1, 0, 1, 1, 1, 0,-1 ,-1,-1, 0, 1, 1, 1, 0};\r
+ public int getContour(NyARBinRaster i_raster,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException\r
+ {\r
+ return impl_getContour(i_raster,0,i_entry_x,i_entry_y,i_array_size,o_coord_x,o_coord_y);\r
+ }\r
+ /**\r
+ * \r
+ * @param i_raster\r
+ * @param i_th\r
+ * 画像を2値化するための閾値。暗点<=i_th<明点となります。\r
+ * @param i_entry_x\r
+ * 輪郭の追跡開始点を指定します。\r
+ * @param i_entry_y\r
+ * @param i_array_size\r
+ * @param o_coord_x\r
+ * @param o_coord_y\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int getContour(NyARGrayscaleRaster i_raster,int i_th,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException\r
+ {\r
+ return impl_getContour(i_raster,i_th,i_entry_x,i_entry_y,i_array_size,o_coord_x,o_coord_y);\r
+ }\r
+\r
+ /**\r
+ * ラスタのエントリポイントから辿れる輪郭線を配列に返します。\r
+ * @param i_raster\r
+ * @param i_th\r
+ * 暗点<=th<明点\r
+ * @param i_entry_x\r
+ * @param i_entry_y\r
+ * @param i_array_size\r
+ * @param o_coord_x\r
+ * @param o_coord_y\r
+ * @return\r
+ * 輪郭線の長さを返します。\r
+ * @throws NyARException\r
+ */\r
+ private int impl_getContour(INyARRaster i_raster,int i_th,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException\r
+ {\r
+ final int[] xdir = _getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};\r
+ final int[] ydir = _getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};\r
+\r
+ final int[] i_buf=(int[])i_raster.getBufferReader().getBuffer();\r
+ final int width=i_raster.getWidth();\r
+ final int height=i_raster.getHeight();\r
+ //クリップ領域の上端に接しているポイントを得る。\r
+\r
+\r
+ int coord_num = 1;\r
+ o_coord_x[0] = i_entry_x;\r
+ o_coord_y[0] = i_entry_y;\r
+ int dir = 5;\r
+\r
+ int c = i_entry_x;\r
+ int r = i_entry_y;\r
+ for (;;) {\r
+ dir = (dir + 5) % 8;//dirの正規化\r
+ //ここは頑張ればもっと最適化できると思うよ。\r
+ //4隅以外の境界接地の場合に、境界チェックを省略するとかね。\r
+ if(c>=1 && c<width-1 && r>=1 && r<height-1){\r
+ for(;;){//gotoのエミュレート用のfor文\r
+ //境界に接していないとき(暗点判定)\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {\r
+ break;\r
+ }\r
+/*\r
+ try{\r
+ BufferedImage b=new BufferedImage(width,height,ColorSpace.TYPE_RGB);\r
+ NyARRasterImageIO.copy(i_raster, b);\r
+ ImageIO.write(b,"png",new File("bug.png"));\r
+ }catch(Exception e){\r
+ \r
+ }*/\r
+ //8方向全て調べたけどラベルが無いよ?\r
+ throw new NyARException(); \r
+ }\r
+ }else{\r
+ //境界に接しているとき \r
+ int i;\r
+ for (i = 0; i < 8; i++){ \r
+ final int x=c + xdir[dir];\r
+ final int y=r + ydir[dir];\r
+ //境界チェック\r
+ if(x>=0 && x<width && y>=0 && y<height){\r
+ if (i_buf[(y)*width+(x)] <= i_th) {\r
+ break;\r
+ }\r
+ }\r
+ dir++;//倍長テーブルを参照するので問題なし\r
+ }\r
+ if (i == 8) {\r
+ //8方向全て調べたけどラベルが無いよ?\r
+ throw new NyARException();// return(-1);\r
+ } \r
+ }\r
+ \r
+ dir=dir% 8;//dirの正規化\r
+\r
+ // xcoordとycoordをc,rにも保存\r
+ c = c + xdir[dir];\r
+ r = r + ydir[dir];\r
+ o_coord_x[coord_num] = c;\r
+ o_coord_y[coord_num] = r;\r
+ // 終了条件判定\r
+ if (c == i_entry_x && r == i_entry_y){\r
+ coord_num++;\r
+ break;\r
+ }\r
+ coord_num++;\r
+ if (coord_num == i_array_size) {\r
+ //輪郭が末端に達した\r
+ return coord_num;\r
+ }\r
+ }\r
+ return coord_num;\r
+ }\r
+ public int getContour(NyARLabelingImage i_raster,int i_entry_x,int i_entry_y,int i_array_size,int[] o_coord_x,int[] o_coord_y) throws NyARException\r
+ { \r
+ final int[] xdir = _getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};\r
+ final int[] ydir = _getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};\r
+\r
+ final int[] i_buf=(int[])i_raster.getBufferReader().getBuffer();\r
+ final int width=i_raster.getWidth();\r
+ final int height=i_raster.getHeight();\r
+ //クリップ領域の上端に接しているポイントを得る。\r
+ int sx=i_entry_x;\r
+ int sy=i_entry_y;\r
+\r
+ int coord_num = 1;\r
+ o_coord_x[0] = sx;\r
+ o_coord_y[0] = sy;\r
+ int dir = 5;\r
+\r
+ int c = o_coord_x[0];\r
+ int r = o_coord_y[0];\r
+ for (;;) {\r
+ dir = (dir + 5) % 8;//dirの正規化\r
+ //ここは頑張ればもっと最適化できると思うよ。\r
+ //4隅以外の境界接地の場合に、境界チェックを省略するとかね。\r
+ if(c>=1 && c<width-1 && r>=1 && r<height-1){\r
+ for(;;){//gotoのエミュレート用のfor文\r
+ //境界に接していないとき\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+ break;\r
+ }\r
+ dir++;\r
+ if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] > 0) {\r
+ break;\r
+ }\r
+ //8方向全て調べたけどラベルが無いよ?\r
+ throw new NyARException(); \r
+ }\r
+ }else{\r
+ //境界に接しているとき\r
+ int i;\r
+ for (i = 0; i < 8; i++){ \r
+ final int x=c + xdir[dir];\r
+ final int y=r + ydir[dir];\r
+ //境界チェック\r
+ if(x>=0 && x<width && y>=0 && y<height){\r
+ if (i_buf[(y)*width+(x)] > 0) {\r
+ break;\r
+ }\r
+ }\r
+ dir++;//倍長テーブルを参照するので問題なし\r
+ }\r
+ if (i == 8) {\r
+ //8方向全て調べたけどラベルが無いよ?\r
+ throw new NyARException();// return(-1);\r
+ } \r
+ }\r
+ \r
+ dir=dir% 8;//dirの正規化\r
+\r
+ // xcoordとycoordをc,rにも保存\r
+ c = c + xdir[dir];\r
+ r = r + ydir[dir];\r
+ o_coord_x[coord_num] = c;\r
+ o_coord_y[coord_num] = r;\r
+ // 終了条件判定\r
+ if (c == sx && r == sy){\r
+ coord_num++;\r
+ break;\r
+ }\r
+ coord_num++;\r
+ if (coord_num == i_array_size) {\r
+ //輪郭が末端に達した\r
+ return coord_num;\r
+ }\r
+ }\r
+ return coord_num;\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.param.NyARObserv2IdealMap;\r
+import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;\r
+import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;\r
+\r
+\r
+\r
+/**\r
+ * 頂点集合を一次方程式のパラメータに変換します。\r
+ * \r
+ *\r
+ */\r
+public class Coord2Linear\r
+{\r
+ private final double[] _xpos;\r
+ private final double[] _ypos; \r
+ private final INyARPca2d _pca;\r
+ private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();\r
+ private final double[] __getSquareLine_mean=new double[2];\r
+ private final double[] __getSquareLine_ev=new double[2];\r
+ private final NyARObserv2IdealMap _dist_factor;\r
+ public Coord2Linear(NyARIntSize i_size,NyARCameraDistortionFactor i_distfactor_ref)\r
+ {\r
+ //歪み計算テーブルを作ると、8*width/height*2の領域を消費します。\r
+ //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。\r
+ this._dist_factor = new NyARObserv2IdealMap(i_distfactor_ref,i_size);\r
+\r
+\r
+ // 輪郭バッファ\r
+ this._pca=new NyARPca2d_MatrixPCA_O2();\r
+ this._xpos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height\r
+ this._ypos=new double[i_size.w+i_size.h];//最大辺長はthis._width+this._height\r
+ return;\r
+ }\r
+\r
+\r
+ /**\r
+ * 輪郭点集合からay+bx+c=0の直線式を計算します。\r
+ * @param i_st\r
+ * @param i_ed\r
+ * @param i_xcoord\r
+ * @param i_ycoord\r
+ * @param i_cood_num\r
+ * @param o_line\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public boolean coord2Line(int i_st,int i_ed,int[] i_xcoord, int[] i_ycoord,int i_cood_num, NyARLinear o_line) throws NyARException\r
+ {\r
+ //頂点を取得\r
+ int n,st,ed;\r
+ double w1;\r
+ \r
+ //探索区間の決定\r
+ if(i_ed>=i_st){\r
+ //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき\r
+ w1 = (double) (i_ed - i_st + 1) * 0.05 + 0.5;\r
+ //探索区間の決定\r
+ st = (int) (i_st+w1);\r
+ ed = (int) (i_ed - w1);\r
+ }else{\r
+ //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき\r
+ w1 = (double) (i_ed+i_cood_num-i_st+1)%i_cood_num * 0.05 + 0.5;\r
+ //探索区間の決定\r
+ st = (int) (i_st+w1)%i_cood_num;\r
+ ed = (int) (i_ed+i_cood_num-w1)%i_cood_num;\r
+ }\r
+ //探索区間数を確認\r
+ if(st<=ed){\r
+ //探索区間は1区間\r
+ n = ed - st + 1;\r
+ this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos,0);\r
+ }else{\r
+ //探索区間は2区間\r
+ n=ed+1+i_cood_num-st;\r
+ this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st,i_cood_num-st,this._xpos,this._ypos,0);\r
+ this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, 0,ed+1,this._xpos,this._ypos,i_cood_num-st);\r
+ }\r
+ //要素数の確認\r
+ if (n < 2) {\r
+ // nが2以下でmatrix.PCAを計算することはできないので、エラー\r
+ return false;\r
+ }\r
+ //主成分分析する。\r
+ final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;\r
+ final double[] mean=this.__getSquareLine_mean;\r
+\r
+ \r
+ this._pca.pca(this._xpos,this._ypos,n,evec, this.__getSquareLine_ev,mean);\r
+ o_line.dy = evec.m01;// line[i][0] = evec->m[1];\r
+ o_line.dx = -evec.m00;// line[i][1] = -evec->m[0];\r
+ o_line.c = -(o_line.dy * mean[0] + o_line.dx * mean[1]);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);\r
+\r
+ return true;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+/**\r
+ * 座標店集合(輪郭線)から、四角系の頂点候補点を計算します。\r
+ *\r
+ */\r
+public class Coord2SquareVertexIndexes\r
+{\r
+ private static final double VERTEX_FACTOR = 1.0;// 線検出のファクタ \r
+ private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();\r
+ private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();\r
+ public Coord2SquareVertexIndexes()\r
+ {\r
+ return;\r
+ }\r
+ /**\r
+ * 座標集合から、頂点候補になりそうな場所を4箇所探して、そのインデクス番号を返します。\r
+ * @param i_x_coord\r
+ * @param i_y_coord\r
+ * @param i_coord_num\r
+ * @param i_area\r
+ * @param o_vertex\r
+ * @return\r
+ */\r
+ public boolean getVertexIndexes(int[] i_x_coord, int[] i_y_coord, int i_coord_num, int i_area, int[] o_vertex)\r
+ {\r
+ final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;\r
+ final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;\r
+ int vertex1_index=getFarPoint(i_x_coord,i_y_coord,i_coord_num,0);\r
+ int prev_vertex_index=(vertex1_index+i_coord_num)%i_coord_num;\r
+ int v1=getFarPoint(i_x_coord,i_y_coord,i_coord_num,vertex1_index);\r
+ final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;\r
+\r
+ o_vertex[0] = vertex1_index;\r
+\r
+ if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, vertex1_index, v1, thresh)) {\r
+ return false;\r
+ }\r
+ if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v1,prev_vertex_index, thresh)) {\r
+ return false;\r
+ }\r
+\r
+ int v2;\r
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
+ o_vertex[1] = wv1.vertex[0];\r
+ o_vertex[2] = v1;\r
+ o_vertex[3] = wv2.vertex[0];\r
+ } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {\r
+ //頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。\r
+ if(v1>=vertex1_index){\r
+ v2 = (v1-vertex1_index)/2+vertex1_index;\r
+ }else{\r
+ v2 = ((v1+i_coord_num-vertex1_index)/2+vertex1_index)%i_coord_num;\r
+ }\r
+ if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, vertex1_index, v2, thresh)) {\r
+ return false;\r
+ }\r
+ if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, v1, thresh)) {\r
+ return false;\r
+ }\r
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
+ o_vertex[1] = wv1.vertex[0];\r
+ o_vertex[2] = wv2.vertex[0];\r
+ o_vertex[3] = v1;\r
+ } else {\r
+ return false;\r
+ }\r
+ } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {\r
+ //v2 = (v1+ end_of_coord)/2;\r
+ if(v1<=prev_vertex_index){\r
+ v2 = (v1+prev_vertex_index)/2;\r
+ }else{\r
+ v2 = ((v1+i_coord_num+prev_vertex_index)/2)%i_coord_num;\r
+ \r
+ }\r
+ if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, v1, v2, thresh)) {\r
+ return false;\r
+ }\r
+ if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, prev_vertex_index, thresh)) {\r
+ return false;\r
+ }\r
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {\r
+ o_vertex[1] = v1;\r
+ o_vertex[2] = wv1.vertex[0];\r
+ o_vertex[3] = wv2.vertex[0];\r
+ } else {\r
+ \r
+ return false;\r
+ }\r
+ } else {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * i_pointの輪郭座標から、最も遠方にある輪郭座標のインデクスを探します。\r
+ * @param i_xcoord\r
+ * @param i_ycoord\r
+ * @param i_coord_num\r
+ * @return\r
+ */\r
+ private static int getFarPoint(int[] i_coord_x, int[] i_coord_y,int i_coord_num,int i_point)\r
+ {\r
+ //\r
+ final int sx = i_coord_x[i_point];\r
+ final int sy = i_coord_y[i_point];\r
+ int d = 0;\r
+ int w, x, y;\r
+ int ret = 0;\r
+ for (int i = i_point+1; i < i_coord_num; i++) {\r
+ x = i_coord_x[i] - sx;\r
+ y = i_coord_y[i] - sy;\r
+ w = x * x + y * y;\r
+ if (w > d) {\r
+ d = w;\r
+ ret = i;\r
+ }\r
+ }\r
+ for (int i = 0; i < i_point; i++) {\r
+ x = i_coord_x[i] - sx;\r
+ y = i_coord_y[i] - sy;\r
+ w = x * x + y * y;\r
+ if (w > d) {\r
+ d = w;\r
+ ret = i;\r
+ }\r
+ } \r
+ return ret;\r
+ } \r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * get_vertex関数を切り離すためのクラス\r
+ * \r
+ */\r
+final class NyARVertexCounter\r
+{\r
+ public final int[] vertex = new int[10];// 6まで削れる\r
+\r
+ public int number_of_vertex;\r
+\r
+ private double thresh;\r
+\r
+ private int[] x_coord;\r
+\r
+ private int[] y_coord;\r
+\r
+ public boolean getVertex(int[] i_x_coord, int[] i_y_coord,int i_coord_len,int st, int ed, double i_thresh)\r
+ {\r
+ this.number_of_vertex = 0;\r
+ this.thresh = i_thresh;\r
+ this.x_coord = i_x_coord;\r
+ this.y_coord = i_y_coord;\r
+ return get_vertex(st, ed,i_coord_len);\r
+ }\r
+\r
+ /**\r
+ * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数\r
+ * \r
+ * @param x_coord\r
+ * @param y_coord\r
+ * @param st\r
+ * @param ed\r
+ * @param thresh\r
+ * @return\r
+ */\r
+ private boolean get_vertex(int st, int ed,int i_coord_len)\r
+ {\r
+ //メモ:座標値は65536を超えなければint32で扱って大丈夫なので変更。\r
+ //dmaxは4乗なのでやるとしてもint64じゃないとマズイ\r
+ int v1 = 0;\r
+ final int[] lx_coord = this.x_coord;\r
+ final int[] ly_coord = this.y_coord;\r
+ final int a = ly_coord[ed] - ly_coord[st];\r
+ final int b = lx_coord[st] - lx_coord[ed];\r
+ final int c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];\r
+ double dmax = 0;\r
+ if(st<ed){\r
+ //stとedが1区間\r
+ for (int i = st + 1; i < ed; i++) {\r
+ final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+ if (d * d > dmax) {\r
+ dmax = d * d;\r
+ v1 = i;\r
+ }\r
+ }\r
+ }else{\r
+ //stとedが2区間\r
+ for (int i = st + 1; i < i_coord_len; i++) {\r
+ final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+ if (d * d > dmax) {\r
+ dmax = d * d;\r
+ v1 = i;\r
+ }\r
+ }\r
+ for (int i = 0; i < ed; i++) {\r
+ final double d = a * lx_coord[i] + b * ly_coord[i] + c;\r
+ if (d * d > dmax) {\r
+ dmax = d * d;\r
+ v1 = i;\r
+ }\r
+ }\r
+ }\r
+\r
+ \r
+ if (dmax / (double)(a * a + b * b) > thresh) {\r
+ if (!get_vertex(st, v1,i_coord_len)) {\r
+ return false;\r
+ }\r
+ if (number_of_vertex > 5) {\r
+ return false;\r
+ }\r
+ vertex[number_of_vertex] = v1;// vertex[(*vnum)] = v1;\r
+ number_of_vertex++;// (*vnum)++;\r
+\r
+ if (!get_vertex(v1, ed,i_coord_len)) {\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+\r
+public interface INyARSquareContourDetector\r
+{\r
+ public interface DetectMarkerCallback\r
+ {\r
+ public void onSquareDetect(INyARSquareContourDetector i_sender,int[] i_coordx,int[] i_coordy,int i_coor_num,int[] i_vertex_index) throws NyARException;\r
+ }\r
+ /**\r
+ *\r
+ * @param i_raster\r
+ * @param o_square_stack\r
+ * @throws NyARException\r
+ */\r
+ public void detectMarkerCB(NyARBinRaster i_raster, DetectMarkerCallback i_callback) throws NyARException;\r
+}\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+/**\r
+ * ARMarkerInfoに相当するクラス。 矩形情報を保持します。\r
+ * \r
+ * directionは方角を表します。\r
+ * 決定しないときはDIRECTION_UNKNOWNを設定してください。\r
+ * \r
+ */\r
+public class NyARSquare\r
+{\r
+ public NyARLinear[] line = NyARLinear.createArray(4);\r
+ public NyARDoublePoint2d[] sqvertex = NyARDoublePoint2d.createArray(4);\r
+ public NyARIntPoint2d[] imvertex = NyARIntPoint2d.createArray(4);\r
+ public NyARSquare()\r
+ {\r
+ for (int i = 0; i < 4; i++)\r
+ {\r
+ this.line[i] = new NyARLinear();\r
+ }\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.LabelOverlapChecker;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabelStack;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabeling_ARToolKit;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+\r
+\r
+public class NyARSquareContourDetector_ARToolKit implements INyARSquareContourDetector\r
+{\r
+ private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
+ private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
+ private final int _width;\r
+ private final int _height;\r
+\r
+ private final NyARLabeling_ARToolKit _labeling;\r
+\r
+ private final NyARLabelingImage _limage;\r
+\r
+ private final LabelOverlapChecker<NyARLabelingLabel> _overlap_checker = new LabelOverlapChecker<NyARLabelingLabel>(32,NyARLabelingLabel.class);\r
+ private final ContourPickup _cpickup=new ContourPickup();\r
+ private final Coord2SquareVertexIndexes _coord2vertex=new Coord2SquareVertexIndexes();\r
+ \r
+ private final int _max_coord;\r
+ private final int[] _xcoord;\r
+ private final int[] _ycoord; \r
+ private final int[] __detectMarker_mkvertex = new int[4];\r
+ /**\r
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARSquareContourDetector_ARToolKit(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
+ {\r
+ this._width = i_size.w;\r
+ this._height = i_size.h;\r
+ this._labeling = new NyARLabeling_ARToolKit();\r
+ this._limage = new NyARLabelingImage(this._width, this._height);\r
+\r
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
+ int number_of_coord = (this._width + this._height) * 2;\r
+\r
+ // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。\r
+ this._max_coord = number_of_coord;\r
+ this._xcoord = new int[number_of_coord];\r
+ this._ycoord = new int[number_of_coord];\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * arDetectMarker2を基にした関数\r
+ * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。\r
+ * directionの確定は行いません。\r
+ * @param i_raster\r
+ * 解析する2値ラスタイメージを指定します。\r
+ * @param o_square_stack\r
+ * 抽出した正方形候補を格納するリスト\r
+ * @throws NyARException\r
+ */\r
+ public final void detectMarkerCB(NyARBinRaster i_raster, DetectMarkerCallback i_callback) throws NyARException\r
+ {\r
+ final NyARLabelingImage limage = this._limage;\r
+\r
+ // ラベル数が0ならここまで\r
+ final int label_num = this._labeling.labeling(i_raster,this._limage);\r
+ if (label_num < 1) {\r
+ return;\r
+ }\r
+\r
+ final NyARLabelingLabelStack stack = limage.getLabelStack();\r
+ //ラベルをソートしておく\r
+ stack.sortByArea();\r
+ //\r
+ final NyARLabelingLabel[] labels = stack.getArray();\r
+\r
+ // デカいラベルを読み飛ばし\r
+ int i;\r
+ for (i = 0; i < label_num; i++) {\r
+ // 検査対象内のラベルサイズになるまで無視\r
+ if (labels[i].area <= AR_AREA_MAX) {\r
+ break;\r
+ }\r
+ }\r
+ final int xsize = this._width;\r
+ final int ysize = this._height;\r
+ final int[] xcoord = this._xcoord;\r
+ final int[] ycoord = this._ycoord;\r
+ final int coord_max = this._max_coord;\r
+ final int[] mkvertex =this.__detectMarker_mkvertex;\r
+ \r
+ final LabelOverlapChecker<NyARLabelingLabel> overlap = this._overlap_checker;\r
+\r
+ //重なりチェッカの最大数を設定\r
+ overlap.setMaxLabels(label_num);\r
+ for (; i < label_num; i++) {\r
+ final NyARLabelingLabel label_pt = labels[i];\r
+ final int label_area = label_pt.area;\r
+ // 検査対象サイズよりも小さくなったら終了\r
+ if (label_area < AR_AREA_MIN) {\r
+ break;\r
+ }\r
+ // クリップ領域が画面の枠に接していれば除外\r
+ if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){\r
+ continue;\r
+ }\r
+ if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){\r
+ continue;\r
+ }\r
+ // 既に検出された矩形との重なりを確認\r
+ if (!overlap.check(label_pt)) {\r
+ // 重なっているようだ。\r
+ continue;\r
+ }\r
+ // 輪郭を取得\r
+ final int coord_num = _cpickup.getContour(limage,limage.getTopClipTangentX(label_pt),label_pt.clip_t, coord_max, xcoord, ycoord);\r
+ if (coord_num == coord_max) {\r
+ // 輪郭が大きすぎる。\r
+ continue;\r
+ }\r
+ //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得\r
+ if (!this._coord2vertex.getVertexIndexes(xcoord, ycoord,coord_num,label_area, mkvertex)) {\r
+ // 頂点の取得が出来なかった\r
+ continue;\r
+ }\r
+ //矩形を発見したことをコールバック関数で通知\r
+ i_callback.onSquareDetect(this,xcoord,ycoord,coord_num,mkvertex);\r
+\r
+ // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
+ overlap.push(label_pt);\r
+ \r
+ }\r
+ return;\r
+ }\r
+\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.LabelOverlapChecker;\r
+import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.raster.NyARBinRaster;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import java.util.*;\r
+\r
+\r
+public class NyARSquareContourDetector_Rle implements INyARSquareContourDetector\r
+{\r
+ private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
+ private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
+ private final int _width;\r
+ private final int _height;\r
+\r
+ private final NyARLabeling_Rle _labeling;\r
+\r
+ private final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> _overlap_checker = new LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo>(32,RleLabelFragmentInfoStack.RleLabelFragmentInfo.class);\r
+ private final ContourPickup _cpickup=new ContourPickup();\r
+ private final RleLabelFragmentInfoStack _stack;\r
+ private final Coord2SquareVertexIndexes _coord2vertex=new Coord2SquareVertexIndexes();\r
+ \r
+ private final int _max_coord;\r
+ private final int[] _xcoord;\r
+ private final int[] _ycoord;\r
+ /**\r
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARSquareContourDetector_Rle(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
+ {\r
+ this._width = i_size.w;\r
+ this._height = i_size.h;\r
+ //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。\r
+ this._labeling = new NyARLabeling_Rle(this._width,this._height);\r
+ this._labeling.setAreaRange(AR_AREA_MAX, AR_AREA_MIN);\r
+ this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
+ \r
+\r
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
+ int number_of_coord = (this._width + this._height) * 2;\r
+\r
+ // 輪郭バッファ\r
+ this._max_coord = number_of_coord;\r
+ this._xcoord = new int[number_of_coord];\r
+ this._ycoord = new int[number_of_coord];\r
+ return;\r
+ }\r
+\r
+ private final int[] __detectMarker_mkvertex = new int[4];\r
+ \r
+ public void detectMarkerCB(NyARBinRaster i_raster, DetectMarkerCallback i_callback) throws NyARException\r
+ {\r
+ final RleLabelFragmentInfoStack flagment=this._stack;\r
+ final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> overlap = this._overlap_checker;\r
+\r
+ // ラベル数が0ならここまで\r
+ final int label_num=this._labeling.labeling(i_raster, 0, i_raster.getHeight(), flagment);\r
+ if (label_num < 1) {\r
+ return;\r
+ }\r
+ //ラベルをソートしておく\r
+ flagment.sortByArea();\r
+ //ラベルリストを取得\r
+ RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
+\r
+ final int xsize = this._width;\r
+ final int ysize = this._height;\r
+ int[] xcoord = this._xcoord;\r
+ int[] ycoord = this._ycoord;\r
+ final int coord_max = this._max_coord;\r
+ final int[] mkvertex =this.__detectMarker_mkvertex;\r
+\r
+\r
+ //重なりチェッカの最大数を設定\r
+ overlap.setMaxLabels(label_num);\r
+\r
+ for (int i=0; i < label_num; i++) {\r
+ final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
+ int label_area = label_pt.area;\r
+ \r
+ // クリップ領域が画面の枠に接していれば除外\r
+ if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
+ continue;\r
+ }\r
+ if (label_pt.clip_t == 0 || label_pt.clip_b == ysize-1){\r
+ continue;\r
+ }\r
+ // 既に検出された矩形との重なりを確認\r
+ if (!overlap.check(label_pt)) {\r
+ // 重なっているようだ。\r
+ continue;\r
+ }\r
+ \r
+ //輪郭を取得\r
+ int coord_num = _cpickup.getContour(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
+ if (coord_num == coord_max) {\r
+ // 輪郭が大きすぎる。\r
+ continue;\r
+ }\r
+ //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得\r
+ if (!this._coord2vertex.getVertexIndexes(xcoord, ycoord,coord_num,label_area, mkvertex)) {\r
+ // 頂点の取得が出来なかった\r
+ continue;\r
+ }\r
+ //矩形を発見したことをコールバック関数で通知\r
+ i_callback.onSquareDetect(this,xcoord,ycoord,coord_num,mkvertex);\r
+\r
+ // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
+ overlap.push(label_pt);\r
+ \r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * デバック用API\r
+ * @return\r
+ */\r
+ public RleLabelFragmentInfoStack _getFragmentStack()\r
+ {\r
+ return this._stack;\r
+ }\r
+\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.squaredetect;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.types.stack.NyObjectStack;\r
+\r
+public class NyARSquareStack extends NyObjectStack<NyARSquare>\r
+{\r
+ public NyARSquareStack(int i_length)\r
+ {\r
+ super(i_length,NyARSquare.class);\r
+\r
+ }\r
+ protected NyARSquare createElement()\r
+ {\r
+ return new NyARSquare();\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+\r
+\r
+/**\r
+ * This class calculates ARMatrix from square information. -- 変換行列を計算するクラス。\r
+ * \r
+ */\r
+public interface INyARTransMat\r
+{\r
+ public void setCenter(double i_x, double i_y);\r
+ public void transMat(NyARSquare i_square, double i_width, NyARTransMatResult o_result) throws NyARException;\r
+ public void transMatContinue(NyARSquare i_square, double i_width, NyARTransMatResult io_result_conv) throws NyARException;\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit (Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.transmat.solver.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.optimize.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+\r
+/**\r
+ * This class calculates ARMatrix from square information and holds it. --\r
+ * 変換行列を計算して、結果を保持するクラス。\r
+ * \r
+ */\r
+public class NyARTransMat implements INyARTransMat\r
+{ \r
+ private final NyARDoublePoint2d _center=new NyARDoublePoint2d(0,0);\r
+ private final NyARTransOffset _offset=new NyARTransOffset();\r
+ private NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+ protected NyARRotMatrix _rotmatrix;\r
+ protected INyARTransportVectorSolver _transsolver;\r
+ protected NyARPartialDifferentiationOptimize _mat_optimize;\r
+\r
+\r
+ private NyARCameraDistortionFactor _ref_dist_factor;\r
+\r
+ /**\r
+ * 派生クラスで自分でメンバオブジェクトを指定したい場合はこちらを使う。\r
+ *\r
+ */\r
+ protected NyARTransMat()\r
+ {\r
+ //_calculator,_rotmatrix,_mat_optimizeをコンストラクタの終了後に\r
+ //作成して割り当ててください。\r
+ return;\r
+ }\r
+ public NyARTransMat(NyARParam i_param) throws NyARException\r
+ {\r
+ final NyARCameraDistortionFactor dist=i_param.getDistortionFactor();\r
+ final NyARPerspectiveProjectionMatrix pmat=i_param.getPerspectiveProjectionMatrix();\r
+ this._transsolver=new NyARTransportVectorSolver(pmat,4);\r
+ //互換性が重要な時は、NyARRotMatrix_ARToolKitを使うこと。\r
+ //理屈はNyARRotMatrix_NyARToolKitもNyARRotMatrix_ARToolKitも同じだけど、少しだけ値がずれる。\r
+ this._rotmatrix = new NyARRotMatrix(pmat);\r
+ this._mat_optimize=new NyARPartialDifferentiationOptimize(pmat);\r
+ this._ref_dist_factor=dist;\r
+ this._projection_mat_ref=pmat;\r
+ }\r
+\r
+ public void setCenter(double i_x, double i_y)\r
+ {\r
+ this._center.x= i_x;\r
+ this._center.y= i_y;\r
+ }\r
+\r
+\r
+\r
+\r
+\r
+\r
+ private final NyARDoublePoint2d[] __transMat_vertex_2d = NyARDoublePoint2d.createArray(4);\r
+ private final NyARDoublePoint3d[] __transMat_vertex_3d = NyARDoublePoint3d.createArray(4);\r
+ private final NyARDoublePoint3d __transMat_trans=new NyARDoublePoint3d();\r
+ \r
+ /**\r
+ * 頂点情報を元に、エラー閾値を計算します。\r
+ * @param i_vertex\r
+ */\r
+ private double makeErrThreshold(NyARDoublePoint2d[] i_vertex)\r
+ {\r
+ double a,b,l1,l2;\r
+ a=i_vertex[0].x-i_vertex[2].x;\r
+ b=i_vertex[0].y-i_vertex[2].y;\r
+ l1=a*a+b*b;\r
+ a=i_vertex[1].x-i_vertex[3].x;\r
+ b=i_vertex[1].y-i_vertex[3].y;\r
+ l2=a*a+b*b;\r
+ return (Math.sqrt(l1>l2?l1:l2))/200;\r
+ }\r
+ \r
+ /**\r
+ * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )\r
+ * \r
+ * @param i_square\r
+ * 計算対象のNyARSquareオブジェクト\r
+ * @param i_direction\r
+ * @param i_width\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public void transMat(final NyARSquare i_square, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
+ {\r
+ final NyARDoublePoint3d trans=this.__transMat_trans;\r
+ \r
+ double err_threshold=makeErrThreshold(i_square.sqvertex);\r
+ \r
+ //平行移動量計算機に、2D座標系をセット\r
+ NyARDoublePoint2d[] vertex_2d=this.__transMat_vertex_2d;\r
+ NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+ this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4); \r
+ this._transsolver.set2dVertex(vertex_2d,4);\r
+ \r
+ //基準矩形の3D座標系を作成\r
+ this._offset.setSquare(i_width,this._center);\r
+\r
+ //回転行列を計算\r
+ this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
+ \r
+ //回転後の3D座標系から、平行移動量を計算\r
+ this._rotmatrix.getPoint3dBatch(this._offset.vertex,vertex_3d,4);\r
+ this._transsolver.solveTransportVector(vertex_3d,trans);\r
+ \r
+ //計算結果の最適化(平行移動量と回転行列の最適化)\r
+ o_result_conv.error=this.optimize(this._rotmatrix, trans, this._transsolver,this._offset.vertex, vertex_2d,err_threshold);\r
+ \r
+ // マトリクスの保存\r
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,o_result_conv);\r
+ return;\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * @see jp.nyatla.nyartoolkit.core.transmat.INyARTransMat#transMatContinue(jp.nyatla.nyartoolkit.core.NyARSquare, int, double, jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult)\r
+ */\r
+ public void transMatContinue(NyARSquare i_square, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
+ {\r
+ final NyARDoublePoint3d trans=this.__transMat_trans;\r
+\r
+ // io_result_convが初期値なら、transMatで計算する。\r
+ if (!o_result_conv.has_value) {\r
+ this.transMat(i_square,i_width, o_result_conv);\r
+ return;\r
+ }\r
+ \r
+ //最適化計算の閾値を決定\r
+ double err_threshold=makeErrThreshold(i_square.sqvertex);\r
+\r
+ \r
+ //平行移動量計算機に、2D座標系をセット\r
+ NyARDoublePoint2d[] vertex_2d=this.__transMat_vertex_2d;\r
+ NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+ this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4); \r
+ this._transsolver.set2dVertex(vertex_2d,4);\r
+ \r
+ //基準矩形の3D座標系を作成\r
+ this._offset.setSquare(i_width,this._center);\r
+\r
+ //回転行列を計算\r
+ this._rotmatrix.initRotByPrevResult(o_result_conv);\r
+ \r
+ //回転後の3D座標系から、平行移動量を計算\r
+ this._rotmatrix.getPoint3dBatch(this._offset.vertex,vertex_3d,4);\r
+ this._transsolver.solveTransportVector(vertex_3d,trans);\r
+\r
+ //現在のエラーレートを計算しておく\r
+ double min_err=errRate(this._rotmatrix,trans, this._offset.vertex, vertex_2d,4,vertex_3d);\r
+ NyARDoubleMatrix33 rot=this.__rot;\r
+ //エラーレートが前回のエラー値より閾値分大きかったらアゲイン\r
+ if(min_err<o_result_conv.error+err_threshold){\r
+ rot.setValue(this._rotmatrix);\r
+ //最適化してみる。\r
+ for (int i = 0;i<5; i++) {\r
+ //変換行列の最適化\r
+ this._mat_optimize.modifyMatrix(rot, trans, this._offset.vertex, vertex_2d, 4);\r
+ double err=errRate(rot,trans,this._offset.vertex, vertex_2d,4,vertex_3d);\r
+ //System.out.println("E:"+err);\r
+ if(min_err-err<err_threshold/2){\r
+ //System.out.println("BREAK");\r
+ break;\r
+ }\r
+ this._transsolver.solveTransportVector(vertex_3d, trans);\r
+ this._rotmatrix.setValue(rot);\r
+ min_err=err;\r
+ }\r
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,o_result_conv);\r
+ }else{\r
+ //回転行列を計算\r
+ this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
+ \r
+ //回転後の3D座標系から、平行移動量を計算\r
+ this._rotmatrix.getPoint3dBatch(this._offset.vertex,vertex_3d,4);\r
+ this._transsolver.solveTransportVector(vertex_3d,trans);\r
+ \r
+ //計算結果の最適化(平行移動量と回転行列の最適化)\r
+ min_err=this.optimize(this._rotmatrix, trans, this._transsolver,this._offset.vertex, vertex_2d,err_threshold);\r
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,o_result_conv);\r
+ }\r
+ o_result_conv.error=min_err;\r
+ return;\r
+ }\r
+ private NyARDoubleMatrix33 __rot=new NyARDoubleMatrix33();\r
+ private double optimize(NyARRotMatrix io_rotmat,NyARDoublePoint3d io_transvec,INyARTransportVectorSolver i_solver,NyARDoublePoint3d[] i_offset_3d,NyARDoublePoint2d[] i_2d_vertex,double i_err_threshold) throws NyARException\r
+ {\r
+ //System.out.println("START");\r
+ NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+ //初期のエラー値を計算\r
+ double min_err=errRate(io_rotmat, io_transvec, i_offset_3d, i_2d_vertex,4,vertex_3d);\r
+ NyARDoubleMatrix33 rot=this.__rot;\r
+ rot.setValue(io_rotmat);\r
+ for (int i = 0;i<5; i++) {\r
+ //変換行列の最適化\r
+ this._mat_optimize.modifyMatrix(rot, io_transvec, i_offset_3d, i_2d_vertex, 4);\r
+ double err=errRate(rot,io_transvec, i_offset_3d, i_2d_vertex,4,vertex_3d);\r
+ //System.out.println("E:"+err);\r
+ if(min_err-err<i_err_threshold){\r
+ //System.out.println("BREAK");\r
+ break;\r
+ }\r
+ i_solver.solveTransportVector(vertex_3d, io_transvec);\r
+ io_rotmat.setValue(rot);\r
+ min_err=err;\r
+ }\r
+ //System.out.println("END");\r
+ return min_err;\r
+ }\r
+ \r
+ //エラーレート計算機\r
+ public double errRate(NyARDoubleMatrix33 io_rot,NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d,int i_number_of_vertex,NyARDoublePoint3d[] o_rot_vertex) throws NyARException\r
+ {\r
+ NyARPerspectiveProjectionMatrix cp = this._projection_mat_ref;\r
+ final double cp00=cp.m00;\r
+ final double cp01=cp.m01;\r
+ final double cp02=cp.m02;\r
+ final double cp11=cp.m11;\r
+ final double cp12=cp.m12;\r
+\r
+ double err=0;\r
+ for(int i=0;i<i_number_of_vertex;i++){\r
+ double x3d,y3d,z3d;\r
+ o_rot_vertex[i].x=x3d=io_rot.m00*i_vertex3d[i].x+io_rot.m01*i_vertex3d[i].y+io_rot.m02*i_vertex3d[i].z;\r
+ o_rot_vertex[i].y=y3d=io_rot.m10*i_vertex3d[i].x+io_rot.m11*i_vertex3d[i].y+io_rot.m12*i_vertex3d[i].z;\r
+ o_rot_vertex[i].z=z3d=io_rot.m20*i_vertex3d[i].x+io_rot.m21*i_vertex3d[i].y+io_rot.m22*i_vertex3d[i].z;\r
+ x3d+=i_trans.x;\r
+ y3d+=i_trans.y;\r
+ z3d+=i_trans.z;\r
+ \r
+ //射影変換\r
+ double x2d=x3d*cp00+y3d*cp01+z3d*cp02;\r
+ double y2d=y3d*cp11+z3d*cp12;\r
+ double h2d=z3d;\r
+ \r
+ //エラーレート計算\r
+ double t1=i_vertex2d[i].x-x2d/h2d;\r
+ double t2=i_vertex2d[i].y-y2d/h2d;\r
+ err+=t1*t1+t2*t2;\r
+ \r
+ }\r
+ return err/i_number_of_vertex;\r
+ } \r
+ \r
+ \r
+ \r
+ /**\r
+ * パラメータで変換行列を更新します。\r
+ * \r
+ * @param i_rot\r
+ * @param i_off\r
+ * @param i_trans\r
+ */\r
+ public void updateMatrixValue(NyARRotMatrix i_rot, NyARDoublePoint3d i_off, NyARDoublePoint3d i_trans,NyARTransMatResult o_result)\r
+ {\r
+ o_result.m00=i_rot.m00;\r
+ o_result.m01=i_rot.m01;\r
+ o_result.m02=i_rot.m02;\r
+ o_result.m03=i_rot.m00 * i_off.x + i_rot.m01 * i_off.y + i_rot.m02 * i_off.z + i_trans.x;\r
+\r
+ o_result.m10 = i_rot.m10;\r
+ o_result.m11 = i_rot.m11;\r
+ o_result.m12 = i_rot.m12;\r
+ o_result.m13 = i_rot.m10 * i_off.x + i_rot.m11 * i_off.y + i_rot.m12 * i_off.z + i_trans.y;\r
+\r
+ o_result.m20 = i_rot.m20;\r
+ o_result.m21 = i_rot.m21;\r
+ o_result.m22 = i_rot.m22;\r
+ o_result.m23 = i_rot.m20 * i_off.x + i_rot.m21 * i_off.y + i_rot.m22 * i_off.z + i_trans.z;\r
+\r
+ o_result.has_value = true;\r
+ return;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+\r
+/**\r
+ * NyARTransMat戻り値専用のNyARMat\r
+ * \r
+ */\r
+public class NyARTransMatResult extends NyARDoubleMatrix34\r
+{\r
+ /**\r
+ * エラーレート。この値はINyARTransMatの派生クラスが使います。\r
+ */\r
+ public double error; \r
+ public boolean has_value = false;\r
+ /**\r
+ * この関数は、0-PIの間で値を返します。\r
+ * @param o_out\r
+ */\r
+ public final void getZXYAngle(NyARDoublePoint3d o_out)\r
+ {\r
+ double sina = this.m21;\r
+ if (sina >= 1.0) {\r
+ o_out.x = Math.PI / 2;\r
+ o_out.y = 0;\r
+ o_out.z = Math.atan2(-this.m10, this.m00);\r
+ } else if (sina <= -1.0) {\r
+ o_out.x = -Math.PI / 2;\r
+ o_out.y = 0;\r
+ o_out.z = Math.atan2(-this.m10, this.m00);\r
+ } else {\r
+ o_out.x = Math.asin(sina);\r
+ o_out.z = Math.atan2(-this.m01, this.m11);\r
+ o_out.y = Math.atan2(-this.m20, this.m22);\r
+ }\r
+ }\r
+ public final void transformVertex(double i_x,double i_y,double i_z,NyARDoublePoint3d o_out)\r
+ {\r
+ o_out.x=this.m00*i_x+this.m01*i_y+this.m02*i_z+this.m03;\r
+ o_out.y=this.m10*i_x+this.m11*i_y+this.m12*i_z+this.m13;\r
+ o_out.z=this.m20*i_x+this.m21*i_y+this.m22*i_z+this.m23;\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.transmat.solver.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit.INyARRotMatrixOptimize;\r
+import jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit.NyARRotMatrixOptimize_O2;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+\r
+/**\r
+ * This class calculates ARMatrix from square information and holds it. --\r
+ * 変換行列を計算して、結果を保持するクラス。\r
+ * \r
+ */\r
+public class NyARTransMat_ARToolKit implements INyARTransMat\r
+{\r
+ private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 5;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5\r
+ private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR = 1.0;// #define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0\r
+ private final static double AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR = 1.0;\r
+\r
+ private final NyARDoublePoint2d _center=new NyARDoublePoint2d(0,0);\r
+ private final NyARTransOffset _offset=new NyARTransOffset();\r
+ protected NyARRotMatrix_ARToolKit _rotmatrix;\r
+ protected INyARTransportVectorSolver _transsolver;\r
+ protected INyARRotMatrixOptimize _mat_optimize;\r
+ private NyARCameraDistortionFactor _ref_dist_factor;\r
+\r
+ /**\r
+ * 派生クラスで自分でメンバオブジェクトを指定したい場合はこちらを使う。\r
+ *\r
+ */\r
+ protected NyARTransMat_ARToolKit()\r
+ {\r
+ //_calculator,_rotmatrix,_mat_optimizeをコンストラクタの終了後に\r
+ //作成して割り当ててください。\r
+ return;\r
+ }\r
+ public NyARTransMat_ARToolKit(NyARParam i_param) throws NyARException\r
+ {\r
+ final NyARCameraDistortionFactor dist=i_param.getDistortionFactor();\r
+ final NyARPerspectiveProjectionMatrix pmat=i_param.getPerspectiveProjectionMatrix();\r
+ this._transsolver=new NyARTransportVectorSolver_ARToolKit(pmat);\r
+ //互換性が重要な時は、NyARRotMatrix_ARToolKitを使うこと。\r
+ //理屈はNyARRotMatrix_NyARToolKitもNyARRotMatrix_ARToolKitも同じだけど、少しだけ値がずれる。\r
+ this._rotmatrix = new NyARRotMatrix_ARToolKit_O2(pmat);\r
+ this._mat_optimize=new NyARRotMatrixOptimize_O2(pmat);\r
+ this._ref_dist_factor=dist;\r
+ }\r
+\r
+ public void setCenter(double i_x, double i_y)\r
+ {\r
+ this._center.x= i_x;\r
+ this._center.y= i_y;\r
+ }\r
+\r
+\r
+ private final NyARDoublePoint2d[] __transMat_vertex_2d = NyARDoublePoint2d.createArray(4);\r
+ private final NyARDoublePoint3d[] __transMat_vertex_3d = NyARDoublePoint3d.createArray(4);\r
+ private final NyARDoublePoint3d __transMat_trans=new NyARDoublePoint3d();\r
+ /**\r
+ * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )\r
+ * \r
+ * @param i_square\r
+ * 計算対象のNyARSquareオブジェクト\r
+ * @param i_width\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public void transMat(final NyARSquare i_square, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
+ {\r
+ final NyARDoublePoint3d trans=this.__transMat_trans;\r
+ \r
+ //平行移動量計算機に、2D座標系をセット\r
+ NyARDoublePoint2d[] vertex_2d=this.__transMat_vertex_2d;\r
+ NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+ this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4); \r
+ this._transsolver.set2dVertex(vertex_2d,4);\r
+ \r
+ //基準矩形の3D座標系を作成\r
+ this._offset.setSquare(i_width,this._center);\r
+\r
+ //回転行列を計算\r
+ this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
+ \r
+ //回転後の3D座標系から、平行移動量を計算\r
+ this._rotmatrix.getPoint3dBatch(this._offset.vertex,vertex_3d,4);\r
+ this._transsolver.solveTransportVector(vertex_3d,trans);\r
+ \r
+ //計算結果の最適化(平行移動量と回転行列の最適化)\r
+ o_result_conv.error=this.optimize(this._rotmatrix, trans, this._transsolver,this._offset.vertex, vertex_2d);\r
+ \r
+ // マトリクスの保存\r
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,o_result_conv);\r
+ return;\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * @see jp.nyatla.nyartoolkit.core.transmat.INyARTransMat#transMatContinue(jp.nyatla.nyartoolkit.core.NyARSquare, int, double, jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult)\r
+ */\r
+ public void transMatContinue(NyARSquare i_square, double i_width, NyARTransMatResult o_result_conv) throws NyARException\r
+ {\r
+ final NyARDoublePoint3d trans=this.__transMat_trans;\r
+\r
+ // io_result_convが初期値なら、transMatで計算する。\r
+ if (!o_result_conv.has_value) {\r
+ this.transMat(i_square, i_width, o_result_conv);\r
+ return;\r
+ }\r
+ \r
+ //平行移動量計算機に、2D座標系をセット\r
+ NyARDoublePoint2d[] vertex_2d=this.__transMat_vertex_2d;\r
+ NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+ this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4); \r
+ this._transsolver.set2dVertex(vertex_2d,4);\r
+ \r
+ //基準矩形の3D座標系を作成\r
+ this._offset.setSquare(i_width,this._center);\r
+\r
+ //回転行列を計算\r
+ this._rotmatrix.initRotByPrevResult(o_result_conv);\r
+ \r
+ //回転後の3D座標系から、平行移動量を計算\r
+ this._rotmatrix.getPoint3dBatch(this._offset.vertex,vertex_3d,4);\r
+ this._transsolver.solveTransportVector(vertex_3d,trans);\r
+ \r
+ //計算結果の最適化(平行移動量と回転行列の最適化)\r
+ double err=this.optimize(this._rotmatrix, trans, this._transsolver, this._offset.vertex, vertex_2d);\r
+ \r
+ // マトリクスの保存\r
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,o_result_conv);\r
+ \r
+ // エラー値が許容範囲でなければTransMatをやり直し\r
+ if (err > AR_GET_TRANS_CONT_MAT_MAX_FIT_ERROR) {\r
+ // rotationを矩形情報で初期化\r
+ this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);\r
+ //回転行列の平行移動量の計算\r
+ this._rotmatrix.getPoint3dBatch(this._offset.vertex,vertex_3d,4);\r
+ this._transsolver.solveTransportVector(vertex_3d,trans);\r
+ //計算結果の最適化(this._rotmatrix,trans)\r
+ final double err2=this.optimize(this._rotmatrix, trans, this._transsolver, this._offset.vertex, vertex_2d);\r
+ //エラー値が低かったら値を差換え\r
+ if (err2 < err) {\r
+ // 良い値が取れたら、差換え\r
+ this.updateMatrixValue(this._rotmatrix, this._offset.point, trans,o_result_conv);\r
+ }\r
+ err=err2;\r
+ }\r
+ //エラー値保存\r
+ o_result_conv.error=err;\r
+ return;\r
+ }\r
+ private double optimize(NyARRotMatrix_ARToolKit io_rotmat,NyARDoublePoint3d io_transvec,INyARTransportVectorSolver i_solver,NyARDoublePoint3d[] i_offset_3d,NyARDoublePoint2d[] i_2d_vertex) throws NyARException\r
+ {\r
+ NyARDoublePoint3d[] vertex_3d=this.__transMat_vertex_3d;\r
+ double err = -1;\r
+ //System.out.println("START");\r
+ // ループを抜けるタイミングをARToolKitと合わせるために変なことしてます。 \r
+ for (int i = 0;; i++) {\r
+ // <arGetTransMat3>\r
+ err = this._mat_optimize.modifyMatrix(io_rotmat, io_transvec, i_offset_3d, i_2d_vertex);\r
+ io_rotmat.getPoint3dBatch(i_offset_3d,vertex_3d,4);\r
+ i_solver.solveTransportVector(vertex_3d, io_transvec);\r
+ \r
+ err = this._mat_optimize.modifyMatrix(io_rotmat, io_transvec, i_offset_3d, i_2d_vertex);\r
+ //System.out.println("E:"+err*4);\r
+ // //</arGetTransMat3>\r
+ if (err < AR_GET_TRANS_MAT_MAX_FIT_ERROR || i == AR_GET_TRANS_MAT_MAX_LOOP_COUNT - 1) {\r
+ break;\r
+ }\r
+ io_rotmat.getPoint3dBatch(i_offset_3d,vertex_3d,4);\r
+ i_solver.solveTransportVector(vertex_3d, io_transvec);\r
+ }\r
+ //System.out.println("END");\r
+ return err;\r
+ } \r
+ /**\r
+ * パラメータで変換行列を更新します。\r
+ * \r
+ * @param i_rot\r
+ * @param i_off\r
+ * @param i_trans\r
+ */\r
+ public void updateMatrixValue(NyARRotMatrix i_rot, NyARDoublePoint3d i_off, NyARDoublePoint3d i_trans,NyARTransMatResult o_result)\r
+ {\r
+ o_result.m00=i_rot.m00;\r
+ o_result.m01=i_rot.m01;\r
+ o_result.m02=i_rot.m02;\r
+ o_result.m03=i_rot.m00 * i_off.x + i_rot.m01 * i_off.y + i_rot.m02 * i_off.z + i_trans.x;\r
+\r
+ o_result.m10 = i_rot.m10;\r
+ o_result.m11 = i_rot.m11;\r
+ o_result.m12 = i_rot.m12;\r
+ o_result.m13 = i_rot.m10 * i_off.x + i_rot.m11 * i_off.y + i_rot.m12 * i_off.z + i_trans.y;\r
+\r
+ o_result.m20 = i_rot.m20;\r
+ o_result.m21 = i_rot.m21;\r
+ o_result.m22 = i_rot.m22;\r
+ o_result.m23 = i_rot.m20 * i_off.x + i_rot.m21 * i_off.y + i_rot.m22 * i_off.z + i_trans.z;\r
+\r
+ o_result.has_value = true;\r
+ return;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+\r
+final public class NyARTransOffset\r
+{\r
+ public final NyARDoublePoint3d[] vertex=NyARDoublePoint3d.createArray(4);\r
+ public final NyARDoublePoint3d point=new NyARDoublePoint3d(); \r
+ /**\r
+ * 中心位置と辺長から、オフセット情報を作成して設定する。\r
+ * @param i_width\r
+ * @param i_center\r
+ */\r
+ public void setSquare(double i_width,NyARDoublePoint2d i_center)\r
+ {\r
+ final double w_2 = i_width / 2.0;\r
+ \r
+ NyARDoublePoint3d vertex3d_ptr;\r
+ vertex3d_ptr= this.vertex[0];\r
+ vertex3d_ptr.x = -w_2;\r
+ vertex3d_ptr.y = w_2;\r
+ vertex3d_ptr.z = 0.0;\r
+ vertex3d_ptr= this.vertex[1];\r
+ vertex3d_ptr.x = w_2;\r
+ vertex3d_ptr.y = w_2;\r
+ vertex3d_ptr.z = 0.0;\r
+ vertex3d_ptr= this.vertex[2];\r
+ vertex3d_ptr.x = w_2;\r
+ vertex3d_ptr.y = -w_2;\r
+ vertex3d_ptr.z = 0.0;\r
+ vertex3d_ptr= this.vertex[3];\r
+ vertex3d_ptr.x = -w_2;\r
+ vertex3d_ptr.y = -w_2;\r
+ vertex3d_ptr.z = 0.0;\r
+ \r
+ this.point.x=-i_center.x;\r
+ this.point.y=-i_center.y;\r
+ this.point.z=0;\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit (Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.optimize;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.utils.*;\r
+\r
+class TSinCosValue{\r
+ public double cos_val;\r
+ public double sin_val;\r
+ public static TSinCosValue[] createArray(int i_size)\r
+ {\r
+ TSinCosValue[] result=new TSinCosValue[i_size];\r
+ for(int i=0;i<i_size;i++){\r
+ result[i]=new TSinCosValue();\r
+ }\r
+ return result;\r
+ }\r
+}\r
+\r
+/**\r
+ * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算 を繰り返して、変換行列を最適化する。\r
+ * \r
+ */\r
+public class NyARPartialDifferentiationOptimize\r
+{\r
+ private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+\r
+ public NyARPartialDifferentiationOptimize(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+ {\r
+ this._projection_mat_ref = i_projection_mat_ref;\r
+ return;\r
+ }\r
+\r
+ public final void sincos2Rotation_ZXY(TSinCosValue[] i_sincos, NyARDoubleMatrix33 i_rot_matrix)\r
+ {\r
+ final double sina = i_sincos[0].sin_val;\r
+ final double cosa = i_sincos[0].cos_val;\r
+ final double sinb = i_sincos[1].sin_val;\r
+ final double cosb = i_sincos[1].cos_val;\r
+ final double sinc = i_sincos[2].sin_val;\r
+ final double cosc = i_sincos[2].cos_val;\r
+ i_rot_matrix.m00 = cosc * cosb - sinc * sina * sinb;\r
+ i_rot_matrix.m01 = -sinc * cosa;\r
+ i_rot_matrix.m02 = cosc * sinb + sinc * sina * cosb;\r
+ i_rot_matrix.m10 = sinc * cosb + cosc * sina * sinb;\r
+ i_rot_matrix.m11 = cosc * cosa;\r
+ i_rot_matrix.m12 = sinc * sinb - cosc * sina * cosb;\r
+ i_rot_matrix.m20 = -cosa * sinb;\r
+ i_rot_matrix.m21 = sina;\r
+ i_rot_matrix.m22 = cosb * cosa;\r
+ }\r
+\r
+ private final void rotation2Sincos_ZXY(NyARDoubleMatrix33 i_rot_matrix, TSinCosValue[] o_out,NyARDoublePoint3d o_ang)\r
+ {\r
+ double x, y, z;\r
+ double sina = i_rot_matrix.m21;\r
+ if (sina >= 1.0) {\r
+ x = Math.PI / 2;\r
+ y = 0;\r
+ z = Math.atan2(-i_rot_matrix.m10, i_rot_matrix.m00);\r
+ } else if (sina <= -1.0) {\r
+ x = -Math.PI / 2;\r
+ y = 0;\r
+ z = Math.atan2(-i_rot_matrix.m10, i_rot_matrix.m00);\r
+ } else {\r
+ x = Math.asin(sina);\r
+ y = Math.atan2(-i_rot_matrix.m20, i_rot_matrix.m22);\r
+ z = Math.atan2(-i_rot_matrix.m01, i_rot_matrix.m11);\r
+ }\r
+ o_ang.x=x;\r
+ o_ang.y=y;\r
+ o_ang.z=z;\r
+ o_out[0].sin_val = Math.sin(x);\r
+ o_out[0].cos_val = Math.cos(x);\r
+ o_out[1].sin_val = Math.sin(y);\r
+ o_out[1].cos_val = Math.cos(y);\r
+ o_out[2].sin_val = Math.sin(z);\r
+ o_out[2].cos_val = Math.cos(z);\r
+ return;\r
+ }\r
+\r
+ /*\r
+ * 射影変換式 基本式 ox=(cosc * cosb - sinc * sina * sinb)*ix+(-sinc * cosa)*iy+(cosc * sinb + sinc * sina * cosb)*iz+i_trans.x; oy=(sinc * cosb + cosc * sina *\r
+ * sinb)*ix+(cosc * cosa)*iy+(sinc * sinb - cosc * sina * cosb)*iz+i_trans.y; oz=(-cosa * sinb)*ix+(sina)*iy+(cosb * cosa)*iz+i_trans.z;\r
+ * \r
+ * double ox=(cosc * cosb)*ix+(-sinc * sina * sinb)*ix+(-sinc * cosa)*iy+(cosc * sinb)*iz + (sinc * sina * cosb)*iz+i_trans.x; double oy=(sinc * cosb)*ix\r
+ * +(cosc * sina * sinb)*ix+(cosc * cosa)*iy+(sinc * sinb)*iz+(- cosc * sina * cosb)*iz+i_trans.y; double oz=(-cosa * sinb)*ix+(sina)*iy+(cosb *\r
+ * cosa)*iz+i_trans.z;\r
+ * \r
+ * sina,cosaについて解く cx=(cp00*(-sinc*sinb*ix+sinc*cosb*iz)+cp01*(cosc*sinb*ix-cosc*cosb*iz)+cp02*(iy))*sina\r
+ * +(cp00*(-sinc*iy)+cp01*((cosc*iy))+cp02*(-sinb*ix+cosb*iz))*cosa\r
+ * +(cp00*(i_trans.x+cosc*cosb*ix+cosc*sinb*iz)+cp01*((i_trans.y+sinc*cosb*ix+sinc*sinb*iz))+cp02*(i_trans.z));\r
+ * cy=(cp11*(cosc*sinb*ix-cosc*cosb*iz)+cp12*(iy))*sina +(cp11*((cosc*iy))+cp12*(-sinb*ix+cosb*iz))*cosa\r
+ * +(cp11*((i_trans.y+sinc*cosb*ix+sinc*sinb*iz))+cp12*(i_trans.z)); ch=(iy)*sina +(-sinb*ix+cosb*iz)*cosa +i_trans.z; sinb,cosb hx=(cp00*(-sinc *\r
+ * sina*ix+cosc*iz)+cp01*(cosc * sina*ix+sinc*iz)+cp02*(-cosa*ix))*sinb +(cp01*(sinc*ix-cosc * sina*iz)+cp00*(cosc*ix+sinc * sina*iz)+cp02*(cosa*iz))*cosb\r
+ * +(cp00*(i_trans.x+(-sinc*cosa)*iy)+cp01*(i_trans.y+(cosc * cosa)*iy)+cp02*(i_trans.z+(sina)*iy)); double hy=(cp11*(cosc *\r
+ * sina*ix+sinc*iz)+cp12*(-cosa*ix))*sinb +(cp11*(sinc*ix-cosc * sina*iz)+cp12*(cosa*iz))*cosb +(cp11*(i_trans.y+(cosc *\r
+ * cosa)*iy)+cp12*(i_trans.z+(sina)*iy)); double h =((-cosa*ix)*sinb +(cosa*iz)*cosb +i_trans.z+(sina)*iy); パラメータ返還式 L=2*Σ(d[n]*e[n]+a[n]*b[n])\r
+ * J=2*Σ(d[n]*f[n]+a[n]*c[n])/L K=2*Σ(-e[n]*f[n]+b[n]*c[n])/L M=Σ(-e[n]^2+d[n]^2-b[n]^2+a[n]^2)/L 偏微分式 +J*cos(x) +K*sin(x) -sin(x)^2 +cos(x)^2\r
+ * +2*M*cos(x)*sin(x)\r
+ */\r
+ private double optimizeParamX(TSinCosValue i_angle_y, TSinCosValue i_angle_z, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d, int i_number_of_vertex, double i_hint_angle) throws NyARException\r
+ {\r
+ NyARPerspectiveProjectionMatrix cp = this._projection_mat_ref;\r
+ final double sinb = i_angle_y.sin_val;\r
+ final double cosb = i_angle_y.cos_val;\r
+ final double sinc = i_angle_z.sin_val;\r
+ final double cosc = i_angle_z.cos_val;\r
+ double L, J, K, M, N, O;\r
+ L = J = K = M = N = O = 0;\r
+ for (int i = 0; i < i_number_of_vertex; i++) {\r
+ double ix, iy, iz;\r
+ ix = i_vertex3d[i].x;\r
+ iy = i_vertex3d[i].y;\r
+ iz = i_vertex3d[i].z;\r
+\r
+ final double cp00 = cp.m00;\r
+ final double cp01 = cp.m01;\r
+ final double cp02 = cp.m02;\r
+ final double cp11 = cp.m11;\r
+ final double cp12 = cp.m12;\r
+\r
+ double X0 = (cp00 * (-sinc * sinb * ix + sinc * cosb * iz) + cp01 * (cosc * sinb * ix - cosc * cosb * iz) + cp02 * (iy));\r
+ double X1 = (cp00 * (-sinc * iy) + cp01 * ((cosc * iy)) + cp02 * (-sinb * ix + cosb * iz));\r
+ double X2 = (cp00 * (i_trans.x + cosc * cosb * ix + cosc * sinb * iz) + cp01 * ((i_trans.y + sinc * cosb * ix + sinc * sinb * iz)) + cp02 * (i_trans.z));\r
+ double Y0 = (cp11 * (cosc * sinb * ix - cosc * cosb * iz) + cp12 * (iy));\r
+ double Y1 = (cp11 * ((cosc * iy)) + cp12 * (-sinb * ix + cosb * iz));\r
+ double Y2 = (cp11 * ((i_trans.y + sinc * cosb * ix + sinc * sinb * iz)) + cp12 * (i_trans.z));\r
+ double H0 = (iy);\r
+ double H1 = (-sinb * ix + cosb * iz);\r
+ double H2 = i_trans.z;\r
+\r
+ double VX = i_vertex2d[i].x;\r
+ double VY = i_vertex2d[i].y;\r
+\r
+ double a, b, c, d, e, f;\r
+ a = (VX * H0 - X0);\r
+ b = (VX * H1 - X1);\r
+ c = (VX * H2 - X2);\r
+ d = (VY * H0 - Y0);\r
+ e = (VY * H1 - Y1);\r
+ f = (VY * H2 - Y2);\r
+\r
+ L += d * e + a * b;\r
+ N += d * d + a * a;\r
+ J += d * f + a * c;\r
+ M += e * e + b * b;\r
+ K += e * f + b * c;\r
+ O += f * f + c * c;\r
+\r
+ }\r
+ L *=2;\r
+ J *=2;\r
+ K *=2;\r
+\r
+ return getMinimumErrorAngleFromParam(L,J, K, M, N, O, i_hint_angle);\r
+\r
+\r
+ }\r
+\r
+ private double optimizeParamY(TSinCosValue i_angle_x, TSinCosValue i_angle_z, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d, int i_number_of_vertex, double i_hint_angle) throws NyARException\r
+ {\r
+ NyARPerspectiveProjectionMatrix cp = this._projection_mat_ref;\r
+ final double sina = i_angle_x.sin_val;\r
+ final double cosa = i_angle_x.cos_val;\r
+ final double sinc = i_angle_z.sin_val;\r
+ final double cosc = i_angle_z.cos_val;\r
+ double L, J, K, M, N, O;\r
+ L = J = K = M = N = O = 0;\r
+ for (int i = 0; i < i_number_of_vertex; i++) {\r
+ double ix, iy, iz;\r
+ ix = i_vertex3d[i].x;\r
+ iy = i_vertex3d[i].y;\r
+ iz = i_vertex3d[i].z;\r
+\r
+ final double cp00 = cp.m00;\r
+ final double cp01 = cp.m01;\r
+ final double cp02 = cp.m02;\r
+ final double cp11 = cp.m11;\r
+ final double cp12 = cp.m12;\r
+\r
+ double X0 = (cp00 * (-sinc * sina * ix + cosc * iz) + cp01 * (cosc * sina * ix + sinc * iz) + cp02 * (-cosa * ix));\r
+ double X1 = (cp01 * (sinc * ix - cosc * sina * iz) + cp00 * (cosc * ix + sinc * sina * iz) + cp02 * (cosa * iz));\r
+ double X2 = (cp00 * (i_trans.x + (-sinc * cosa) * iy) + cp01 * (i_trans.y + (cosc * cosa) * iy) + cp02 * (i_trans.z + (sina) * iy));\r
+ double Y0 = (cp11 * (cosc * sina * ix + sinc * iz) + cp12 * (-cosa * ix));\r
+ double Y1 = (cp11 * (sinc * ix - cosc * sina * iz) + cp12 * (cosa * iz));\r
+ double Y2 = (cp11 * (i_trans.y + (cosc * cosa) * iy) + cp12 * (i_trans.z + (sina) * iy));\r
+ double H0 = (-cosa * ix);\r
+ double H1 = (cosa * iz);\r
+ double H2 = i_trans.z + (sina) * iy;\r
+\r
+ double VX = i_vertex2d[i].x;\r
+ double VY = i_vertex2d[i].y;\r
+\r
+ double a, b, c, d, e, f;\r
+ a = (VX * H0 - X0);\r
+ b = (VX * H1 - X1);\r
+ c = (VX * H2 - X2);\r
+ d = (VY * H0 - Y0);\r
+ e = (VY * H1 - Y1);\r
+ f = (VY * H2 - Y2);\r
+\r
+ L += d * e + a * b;\r
+ N += d * d + a * a;\r
+ J += d * f + a * c;\r
+ M += e * e + b * b;\r
+ K += e * f + b * c;\r
+ O += f * f + c * c;\r
+\r
+ }\r
+ L *= 2;\r
+ J *= 2;\r
+ K *= 2;\r
+ return getMinimumErrorAngleFromParam(L,J, K, M, N, O, i_hint_angle);\r
+\r
+ }\r
+\r
+ private double optimizeParamZ(TSinCosValue i_angle_x, TSinCosValue i_angle_y, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d, int i_number_of_vertex, double i_hint_angle) throws NyARException\r
+ {\r
+ NyARPerspectiveProjectionMatrix cp = this._projection_mat_ref;\r
+ final double sina = i_angle_x.sin_val;\r
+ final double cosa = i_angle_x.cos_val;\r
+ final double sinb = i_angle_y.sin_val;\r
+ final double cosb = i_angle_y.cos_val;\r
+ double L, J, K, M, N, O;\r
+ L = J = K = M = N = O = 0;\r
+ for (int i = 0; i < i_number_of_vertex; i++) {\r
+ double ix, iy, iz;\r
+ ix = i_vertex3d[i].x;\r
+ iy = i_vertex3d[i].y;\r
+ iz = i_vertex3d[i].z;\r
+\r
+ final double cp00 = cp.m00;\r
+ final double cp01 = cp.m01;\r
+ final double cp02 = cp.m02;\r
+ final double cp11 = cp.m11;\r
+ final double cp12 = cp.m12;\r
+\r
+ double X0 = (cp00 * (-sina * sinb * ix - cosa * iy + sina * cosb * iz) + cp01 * (ix * cosb + sinb * iz));\r
+ double X1 = (cp01 * (sina * ix * sinb + cosa * iy - sina * iz * cosb) + cp00 * (cosb * ix + sinb * iz));\r
+ double X2 = cp00 * i_trans.x + cp01 * (i_trans.y) + cp02 * (-cosa * sinb) * ix + cp02 * (sina) * iy + cp02 * ((cosb * cosa) * iz + i_trans.z);\r
+ double Y0 = cp11 * (ix * cosb + sinb * iz);\r
+ double Y1 = cp11 * (sina * ix * sinb + cosa * iy - sina * iz * cosb);\r
+ double Y2 = (cp11 * i_trans.y + cp12 * (-cosa * sinb) * ix + cp12 * ((sina) * iy + (cosb * cosa) * iz + i_trans.z));\r
+ double H0 = 0;\r
+ double H1 = 0;\r
+ double H2 = ((-cosa * sinb) * ix + (sina) * iy + (cosb * cosa) * iz + i_trans.z);\r
+\r
+ double VX = i_vertex2d[i].x;\r
+ double VY = i_vertex2d[i].y;\r
+\r
+ double a, b, c, d, e, f;\r
+ a = (VX * H0 - X0);\r
+ b = (VX * H1 - X1);\r
+ c = (VX * H2 - X2);\r
+ d = (VY * H0 - Y0);\r
+ e = (VY * H1 - Y1);\r
+ f = (VY * H2 - Y2);\r
+\r
+ L += d * e + a * b;\r
+ N += d * d + a * a;\r
+ J += d * f + a * c;\r
+ M += e * e + b * b;\r
+ K += e * f + b * c;\r
+ O += f * f + c * c;\r
+\r
+ }\r
+ L *=2;\r
+ J *=2;\r
+ K *=2;\r
+ \r
+ return getMinimumErrorAngleFromParam(L,J, K, M, N, O, i_hint_angle);\r
+ }\r
+ private TSinCosValue[] __angles_in=TSinCosValue.createArray(3);\r
+ private NyARDoublePoint3d __ang=new NyARDoublePoint3d();\r
+ public void modifyMatrix(NyARDoubleMatrix33 io_rot, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d, int i_number_of_vertex) throws NyARException\r
+ {\r
+ TSinCosValue[] angles_in = this.__angles_in;// x,y,z\r
+ NyARDoublePoint3d ang = this.__ang;\r
+\r
+ // ZXY系のsin/cos値を抽出\r
+ rotation2Sincos_ZXY(io_rot, angles_in,ang);\r
+ ang.x += optimizeParamX(angles_in[1], angles_in[2], i_trans, i_vertex3d, i_vertex2d, i_number_of_vertex, ang.x);\r
+ ang.y += optimizeParamY(angles_in[0], angles_in[2], i_trans, i_vertex3d, i_vertex2d, i_number_of_vertex, ang.y);\r
+ ang.z += optimizeParamZ(angles_in[0], angles_in[1], i_trans, i_vertex3d, i_vertex2d, i_number_of_vertex, ang.z);\r
+ io_rot.setZXYAngle(ang.x, ang.y, ang.z);\r
+ return;\r
+ }\r
+ private double[] __sin_table= new double[4];\r
+ /**\r
+ * エラーレートが最小になる点を得る。\r
+ */\r
+ private double getMinimumErrorAngleFromParam(double iL,double iJ, double iK, double iM, double iN, double iO, double i_hint_angle) throws NyARException\r
+ {\r
+ double[] sin_table = this.__sin_table;\r
+\r
+ double M = (iN - iM)/iL;\r
+ double J = iJ/iL;\r
+ double K = -iK/iL;\r
+\r
+ // パラメータからsinテーブルを作成\r
+ // (- 4*M^2-4)*x^4 + (4*K- 4*J*M)*x^3 + (4*M^2 -(K^2- 4)- J^2)*x^2 +(4*J*M- 2*K)*x + J^2-1 = 0\r
+ int number_of_sin = NyAREquationSolver.solve4Equation(-4 * M * M - 4, 4 * K - 4 * J * M, 4 * M * M - (K * K - 4) - J * J, 4 * J * M - 2 * K, J * J - 1, sin_table);\r
+\r
+\r
+ // 最小値2個を得ておく。\r
+ double min_ang_0 = Double.MAX_VALUE;\r
+ double min_ang_1 = Double.MAX_VALUE;\r
+ double min_err_0 = Double.MAX_VALUE;\r
+ double min_err_1 = Double.MAX_VALUE;\r
+ for (int i = 0; i < number_of_sin; i++) {\r
+ // +-cos_v[i]が頂点候補\r
+ double sin_rt = sin_table[i];\r
+ double cos_rt = Math.sqrt(1 - (sin_rt * sin_rt));\r
+ // cosを修復。微分式で0に近い方が正解\r
+ // 0 = 2*cos(x)*sin(x)*M - sin(x)^2 + cos(x)^2 + sin(x)*K + cos(x)*J\r
+ double a1 = 2 * cos_rt * sin_rt * M + sin_rt * (K - sin_rt) + cos_rt * (cos_rt + J);\r
+ double a2 = 2 * (-cos_rt) * sin_rt * M + sin_rt * (K - sin_rt) + (-cos_rt) * ((-cos_rt) + J);\r
+ // 絶対値になおして、真のcos値を得ておく。\r
+ a1 = a1 < 0 ? -a1 : a1;\r
+ a2 = a2 < 0 ? -a2 : a2;\r
+ cos_rt = (a1 < a2) ? cos_rt : -cos_rt;\r
+ double ang = Math.atan2(sin_rt, cos_rt);\r
+ // エラー値を計算\r
+ double err = iN * sin_rt * sin_rt + (iL*cos_rt + iJ) * sin_rt + iM * cos_rt * cos_rt + iK * cos_rt + iO;\r
+ // 最小の2個を獲得する。\r
+ if (min_err_0 > err) {\r
+ min_err_1 = min_err_0;\r
+ min_ang_1 = min_ang_0;\r
+ min_err_0 = err;\r
+ min_ang_0 = ang;\r
+ } else if (min_err_1 > err) {\r
+ min_err_1 = err;\r
+ min_ang_1 = ang;\r
+ }\r
+ }\r
+ // [0]をテスト\r
+ double gap_0;\r
+ gap_0 = min_ang_0 - i_hint_angle;\r
+ if (gap_0 > Math.PI) {\r
+ gap_0 = (min_ang_0 - Math.PI * 2) - i_hint_angle;\r
+ } else if (gap_0 < -Math.PI) {\r
+ gap_0 = (min_ang_0 + Math.PI * 2) - i_hint_angle;\r
+ }\r
+ // [1]をテスト\r
+ double gap_1;\r
+ gap_1 = min_ang_1 - i_hint_angle;\r
+ if (gap_1 > Math.PI) {\r
+ gap_1 = (min_ang_1 - Math.PI * 2) - i_hint_angle;\r
+ } else if (gap_1 < -Math.PI) {\r
+ gap_1 = (min_ang_1 + Math.PI * 2) - i_hint_angle;\r
+ }\r
+ return Math.abs(gap_1) < Math.abs(gap_0) ? gap_1 : gap_0;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public interface INyARRotMatrixOptimize\r
+{\r
+ /**\r
+ * @param io_rot\r
+ * 初期回転行列\r
+ * @param i_trans\r
+ * 初期並進ベクトル\r
+ * @param i_vertex3d\r
+ * 初期3次元座標\r
+ * @param i_vertex2d\r
+ * 画面上の頂点群\r
+ * @return\r
+ * エラーレート\r
+ * @throws NyARException\r
+ */\r
+// public double optimize(NyARRotMatrix io_rotmat,NyARDoublePoint3d io_transvec,INyARTransportVectorSolver i_solver,NyARDoublePoint3d[] i_offset_3d,NyARDoublePoint2d[] i_2d_vertex) throws NyARException;\r
+ public double modifyMatrix(NyARRotMatrix_ARToolKit io_rot, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException;\r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.solver.INyARTransportVectorSolver;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+/**\r
+ * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算\r
+ * を繰り返して、変換行列を最適化する。\r
+ *\r
+ */\r
+public class NyARRotMatrixOptimize implements INyARRotMatrixOptimize\r
+{\r
+ private final static int AR_GET_TRANS_MAT_MAX_LOOP_COUNT = 5;// #define AR_GET_TRANS_MAT_MAX_LOOP_COUNT 5\r
+ private final static double AR_GET_TRANS_MAT_MAX_FIT_ERROR = 1.0;// #define AR_GET_TRANS_MAT_MAX_FIT_ERROR 1.0\r
+ private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+ public NyARRotMatrixOptimize(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+ {\r
+ this._projection_mat_ref=i_projection_mat_ref;\r
+ return;\r
+ }\r
+ final public double optimize(NyARRotMatrix_ARToolKit io_rotmat,NyARDoublePoint3d io_transvec,INyARTransportVectorSolver i_solver,NyARDoublePoint3d[] i_offset_3d,NyARDoublePoint2d[] i_2d_vertex) throws NyARException\r
+ {\r
+ double err = -1;\r
+ /*ループを抜けるタイミングをARToolKitと合わせるために変なことしてます。*/\r
+ for (int i = 0;; i++) {\r
+ // <arGetTransMat3>\r
+ err = modifyMatrix(io_rotmat,io_transvec,i_offset_3d,i_2d_vertex);\r
+ i_solver.solveTransportVector(i_offset_3d, io_transvec);\r
+ err = modifyMatrix(io_rotmat,io_transvec,i_offset_3d,i_2d_vertex); \r
+ // //</arGetTransMat3>\r
+ if (err < AR_GET_TRANS_MAT_MAX_FIT_ERROR || i == AR_GET_TRANS_MAT_MAX_LOOP_COUNT-1) {\r
+ break;\r
+ }\r
+ i_solver.solveTransportVector(i_offset_3d, io_transvec);\r
+ } \r
+ return err;\r
+ }\r
+ \r
+ private final double[][] __modifyMatrix_double1D = new double[8][3];\r
+ /**\r
+ * arGetRot計算を階層化したModifyMatrix 896\r
+ * \r
+ * @param nyrot\r
+ * @param trans\r
+ * @param i_vertex3d\r
+ * [m][3]\r
+ * @param i_vertex2d\r
+ * [n][2]\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double modifyMatrix(NyARRotMatrix_ARToolKit io_rot,NyARDoublePoint3d trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException\r
+ {\r
+ double factor;\r
+ double a2, b2, c2;\r
+ double ma = 0.0, mb = 0.0, mc = 0.0;\r
+ double h, x, y;\r
+ double err, minerr = 0;\r
+ int t1, t2, t3;\r
+ int s1 = 0, s2 = 0, s3 = 0;\r
+\r
+ factor = 10.0 * Math.PI / 180.0;\r
+ double rot0, rot1, rot3, rot4, rot6, rot7;\r
+ double combo00, combo01, combo02, combo03, combo10, combo11, combo12, combo13, combo20, combo21, combo22, combo23;\r
+ double combo02_2, combo02_5, combo02_8, combo02_11;\r
+ double combo22_2, combo22_5, combo22_8, combo22_11;\r
+ double combo12_2, combo12_5, combo12_8, combo12_11;\r
+ // vertex展開\r
+ final double VX00, VX01, VX02, VX10, VX11, VX12, VX20, VX21, VX22, VX30, VX31, VX32;\r
+ NyARDoublePoint3d d_pt;\r
+ d_pt = i_vertex3d[0];\r
+ VX00 = d_pt.x;\r
+ VX01 = d_pt.y;\r
+ VX02 = d_pt.z;\r
+ d_pt = i_vertex3d[1];\r
+ VX10 = d_pt.x;\r
+ VX11 = d_pt.y;\r
+ VX12 = d_pt.z;\r
+ d_pt = i_vertex3d[2];\r
+ VX20 = d_pt.x;\r
+ VX21 = d_pt.y;\r
+ VX22 = d_pt.z;\r
+ d_pt = i_vertex3d[3];\r
+ VX30 = d_pt.x;\r
+ VX31 = d_pt.y;\r
+ VX32 = d_pt.z;\r
+ final double P2D00, P2D01, P2D10, P2D11, P2D20, P2D21, P2D30, P2D31;\r
+ NyARDoublePoint2d d_pt2;\r
+ d_pt2 = i_vertex2d[0];\r
+ P2D00 = d_pt2.x;\r
+ P2D01 = d_pt2.y;\r
+ d_pt2 = i_vertex2d[1];\r
+ P2D10 = d_pt2.x;\r
+ P2D11 = d_pt2.y;\r
+ d_pt2 = i_vertex2d[2];\r
+ P2D20 = d_pt2.x;\r
+ P2D21 = d_pt2.y;\r
+ d_pt2 = i_vertex2d[3];\r
+ P2D30 = d_pt2.x;\r
+ P2D31 = d_pt2.y;\r
+ final NyARPerspectiveProjectionMatrix prjmat = this._projection_mat_ref;\r
+ final double CP0, CP1, CP2, CP4, CP5, CP6, CP8, CP9, CP10;\r
+ CP0 = prjmat.m00;\r
+ CP1 = prjmat.m01;\r
+ CP2 = prjmat.m02;\r
+ CP4 = prjmat.m10;\r
+ CP5 = prjmat.m11;\r
+ CP6 = prjmat.m12;\r
+ CP8 = prjmat.m20;\r
+ CP9 = prjmat.m21;\r
+ CP10 = prjmat.m22;\r
+ combo03 = CP0 * trans.x + CP1 * trans.y + CP2 * trans.z + prjmat.m03;\r
+ combo13 = CP4 * trans.x + CP5 * trans.y + CP6 * trans.z + prjmat.m13;\r
+ combo23 = CP8 * trans.x + CP9 * trans.y + CP10 * trans.z + prjmat.m23;\r
+ double CACA, SASA, SACA, CA, SA;\r
+ double CACACB, SACACB, SASACB, CASB, SASB;\r
+ double SACASC, SACACBSC, SACACBCC, SACACC;\r
+ final double[][] double1D = this.__modifyMatrix_double1D;\r
+\r
+\r
+ final double[] a_factor = double1D[1];\r
+ final double[] sinb = double1D[2];\r
+ final double[] cosb = double1D[3];\r
+ final double[] b_factor = double1D[4];\r
+ final double[] sinc = double1D[5];\r
+ final double[] cosc = double1D[6];\r
+ final double[] c_factor = double1D[7];\r
+ double w, w2;\r
+ double wsin, wcos;\r
+ \r
+ //現在の角度を確保\r
+ final NyARDoublePoint3d angle = io_rot.refAngle();\r
+ a2 = angle.x;\r
+ b2 = angle.y;\r
+ c2 = angle.z;\r
+\r
+ // comboの3行目を先に計算\r
+ for (int i = 0; i < 10; i++) {\r
+ minerr = 1000000000.0;\r
+ // sin-cosテーブルを計算(これが外に出せるとは…。)\r
+ for (int j = 0; j < 3; j++) {\r
+ w2 = factor * (j - 1);\r
+ w = a2 + w2;\r
+ a_factor[j] = w;\r
+ w = b2 + w2;\r
+ b_factor[j] = w;\r
+ sinb[j] = Math.sin(w);\r
+ cosb[j] = Math.cos(w);\r
+ w = c2 + w2;\r
+ c_factor[j] = w;\r
+ sinc[j] = Math.sin(w);\r
+ cosc[j] = Math.cos(w);\r
+ }\r
+ //\r
+ for (t1 = 0; t1 < 3; t1++) {\r
+ SA = Math.sin(a_factor[t1]);\r
+ CA = Math.cos(a_factor[t1]);\r
+ // Optimize\r
+ CACA = CA * CA;\r
+ SASA = SA * SA;\r
+ SACA = SA * CA;\r
+ for (t2 = 0; t2 < 3; t2++) {\r
+ wsin = sinb[t2];\r
+ wcos = cosb[t2];\r
+ CACACB = CACA * wcos;\r
+ SACACB = SACA * wcos;\r
+ SASACB = SASA * wcos;\r
+ CASB = CA * wsin;\r
+ SASB = SA * wsin;\r
+ // comboの計算1\r
+ combo02 = CP0 * CASB + CP1 * SASB + CP2 * wcos;\r
+ combo12 = CP4 * CASB + CP5 * SASB + CP6 * wcos;\r
+ combo22 = CP8 * CASB + CP9 * SASB + CP10 * wcos;\r
+\r
+ combo02_2 = combo02 * VX02 + combo03;\r
+ combo02_5 = combo02 * VX12 + combo03;\r
+ combo02_8 = combo02 * VX22 + combo03;\r
+ combo02_11 = combo02 * VX32 + combo03;\r
+ combo12_2 = combo12 * VX02 + combo13;\r
+ combo12_5 = combo12 * VX12 + combo13;\r
+ combo12_8 = combo12 * VX22 + combo13;\r
+ combo12_11 = combo12 * VX32 + combo13;\r
+ combo22_2 = combo22 * VX02 + combo23;\r
+ combo22_5 = combo22 * VX12 + combo23;\r
+ combo22_8 = combo22 * VX22 + combo23;\r
+ combo22_11 = combo22 * VX32 + combo23;\r
+ for (t3 = 0; t3 < 3; t3++) {\r
+ wsin = sinc[t3];\r
+ wcos = cosc[t3];\r
+ SACASC = SACA * wsin;\r
+ SACACC = SACA * wcos;\r
+ SACACBSC = SACACB * wsin;\r
+ SACACBCC = SACACB * wcos;\r
+\r
+ rot0 = CACACB * wcos + SASA * wcos + SACACBSC - SACASC;\r
+ rot3 = SACACBCC - SACACC + SASACB * wsin + CACA * wsin;\r
+ rot6 = -CASB * wcos - SASB * wsin;\r
+\r
+ combo00 = CP0 * rot0 + CP1 * rot3 + CP2 * rot6;\r
+ combo10 = CP4 * rot0 + CP5 * rot3 + CP6 * rot6;\r
+ combo20 = CP8 * rot0 + CP9 * rot3 + CP10 * rot6;\r
+\r
+ rot1 = -CACACB * wsin - SASA * wsin + SACACBCC - SACACC;\r
+ rot4 = -SACACBSC + SACASC + SASACB * wcos + CACA * wcos;\r
+ rot7 = CASB * wsin - SASB * wcos;\r
+ combo01 = CP0 * rot1 + CP1 * rot4 + CP2 * rot7;\r
+ combo11 = CP4 * rot1 + CP5 * rot4 + CP6 * rot7;\r
+ combo21 = CP8 * rot1 + CP9 * rot4 + CP10 * rot7;\r
+ //\r
+ err = 0.0;\r
+ h = combo20 * VX00 + combo21 * VX01 + combo22_2;\r
+ x = P2D00 - (combo00 * VX00 + combo01 * VX01 + combo02_2) / h;\r
+ y = P2D01 - (combo10 * VX00 + combo11 * VX01 + combo12_2) / h;\r
+ err += x * x + y * y;\r
+ h = combo20 * VX10 + combo21 * VX11 + combo22_5;\r
+ x = P2D10 - (combo00 * VX10 + combo01 * VX11 + combo02_5) / h;\r
+ y = P2D11 - (combo10 * VX10 + combo11 * VX11 + combo12_5) / h;\r
+ err += x * x + y * y;\r
+ h = combo20 * VX20 + combo21 * VX21 + combo22_8;\r
+ x = P2D20 - (combo00 * VX20 + combo01 * VX21 + combo02_8) / h;\r
+ y = P2D21 - (combo10 * VX20 + combo11 * VX21 + combo12_8) / h;\r
+ err += x * x + y * y;\r
+ h = combo20 * VX30 + combo21 * VX31 + combo22_11;\r
+ x = P2D30 - (combo00 * VX30 + combo01 * VX31 + combo02_11) / h;\r
+ y = P2D31 - (combo10 * VX30 + combo11 * VX31 + combo12_11) / h;\r
+ err += x * x + y * y;\r
+ if (err < minerr) {\r
+ minerr = err;\r
+ ma = a_factor[t1];\r
+ mb = b_factor[t2];\r
+ mc = c_factor[t3];\r
+ s1 = t1 - 1;\r
+ s2 = t2 - 1;\r
+ s3 = t3 - 1;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (s1 == 0 && s2 == 0 && s3 == 0) {\r
+ factor *= 0.5;\r
+ }\r
+ a2 = ma;\r
+ b2 = mb;\r
+ c2 = mc;\r
+ }\r
+ io_rot.setAngle(ma, mb, mc);\r
+ /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
+ return minerr / 4;\r
+ } \r
+ \r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 処理構造がわかる程度に展開したNyARRotTransOptimize\r
+ * \r
+ */\r
+public class NyARRotMatrixOptimize_Base implements INyARRotMatrixOptimize\r
+{\r
+ private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+\r
+ public NyARRotMatrixOptimize_Base(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+ {\r
+ this._projection_mat_ref = i_projection_mat_ref;\r
+ return;\r
+ }\r
+ private double[] __createRotationMap_b_map=new double[6];\r
+ private double[] __createRotationMap_c_map=new double[6];\r
+ private double[] __createRotationMap_f=new double[3];\r
+ private void createRotationMap(NyARDoublePoint3d i_angle,double i_factor,NyARDoubleMatrix33[] i_rot_matrix)\r
+ {\r
+ double sina,cosa,sinb,cosb,sinc,cosc;\r
+ double CACA,SASA,SACA,SASB,CASB,SACACB,CACACB,SASACB;\r
+\r
+ \r
+ final double[] f=this.__createRotationMap_f;\r
+ final double[] b_map=this.__createRotationMap_b_map;\r
+ final double[] c_map=this.__createRotationMap_c_map;\r
+ f[0]=-i_factor;\r
+ f[1]=0;\r
+ f[2]=i_factor;\r
+ double ang1,ang2;\r
+ //BとCのsinマップを先に作成\r
+ for(int i=0;i<3;i++)\r
+ {\r
+ ang1=i_angle.y + f[i];\r
+ b_map[i] =Math.sin(ang1);\r
+ b_map[i+3]=Math.cos(ang1);\r
+ ang2=i_angle.z + f[i];\r
+ c_map[i] =Math.sin(ang2);\r
+ c_map[i+3]=Math.cos(ang2);\r
+ }\r
+ int idx=0;\r
+ int t1,t2,t3;\r
+ for (t1 = 0; t1 < 3; t1++){\r
+ ang1=i_angle.x + f[t1];\r
+ sina = Math.sin(ang1);\r
+ cosa = Math.cos(ang1); \r
+ CACA = cosa * cosa;\r
+ SASA = sina * sina;\r
+ SACA = sina * cosa;\r
+\r
+ for (t2=0;t2<3;t2++){\r
+ sinb = b_map[t2];\r
+ cosb = b_map[t2+3];\r
+ SASB = sina * sinb;\r
+ CASB = cosa * sinb;\r
+ SACACB = SACA * cosb;\r
+ CACACB = CACA * cosb;\r
+ SASACB = SASA * cosb; \r
+ for (t3=0;t3<3;t3++) {\r
+ sinc = c_map[t3];\r
+ cosc = c_map[t3+3];\r
+ final NyARDoubleMatrix33 mat_ptr=i_rot_matrix[idx];\r
+ mat_ptr.m00 = CACACB * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;\r
+ mat_ptr.m01 = -CACACB * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;\r
+ mat_ptr.m02 = CASB;\r
+ mat_ptr.m10 = SACACB * cosc - SACA * cosc + SASACB * sinc + CACA * sinc;\r
+ mat_ptr.m11 = -SACACB * sinc + SACA * sinc + SASACB * cosc + CACA * cosc;\r
+ mat_ptr.m12 = SASB;\r
+ mat_ptr.m20 = -CASB * cosc - SASB * sinc;\r
+ mat_ptr.m21 = CASB * sinc - SASB * cosc;\r
+ mat_ptr.m22 = cosb;\r
+ idx++;\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ private final void getNewMatrix(NyARDoubleMatrix33 i_rot, NyARDoublePoint3d i_trans, NyARDoubleMatrix34 o_combo)\r
+ {\r
+ double cp0,cp1,cp2,cp3;\r
+ NyARPerspectiveProjectionMatrix cp=this._projection_mat_ref;\r
+\r
+ cp3=cp.m03;\r
+ cp0=cp.m00;cp1=cp.m01;cp2=cp.m02;\r
+ o_combo.m00=cp0 * i_rot.m00 + cp1 * i_rot.m10 + cp2 * i_rot.m20;\r
+ o_combo.m01=cp0 * i_rot.m01 + cp1 * i_rot.m11 + cp2 * i_rot.m21;\r
+ o_combo.m02=cp0 * i_rot.m02 + cp1 * i_rot.m12 + cp2 * i_rot.m22;\r
+ o_combo.m03=cp0 * i_trans.x + cp1 * i_trans.y + cp2 * i_trans.z +cp3;\r
+\r
+ cp0=cp.m10;cp1=cp.m11;cp2=cp.m12;\r
+ o_combo.m10=cp0 * i_rot.m00 + cp1 * i_rot.m10 + cp2 * i_rot.m20;\r
+ o_combo.m11=cp0 * i_rot.m01 + cp1 * i_rot.m11 + cp2 * i_rot.m21;\r
+ o_combo.m12=cp0 * i_rot.m02 + cp1 * i_rot.m12 + cp2 * i_rot.m22;\r
+ o_combo.m13=cp0 * i_trans.x + cp1 * i_trans.y + cp2 * i_trans.z +cp3;\r
+\r
+ cp0=cp.m20;cp1=cp.m21;cp2=cp.m22;\r
+ o_combo.m20=cp0 * i_rot.m00 + cp1 * i_rot.m10 + cp2 * i_rot.m20;\r
+ o_combo.m21=cp0 * i_rot.m01 + cp1 * i_rot.m11 + cp2 * i_rot.m21;\r
+ o_combo.m22=cp0 * i_rot.m02 + cp1 * i_rot.m12 + cp2 * i_rot.m22;\r
+ o_combo.m23=cp0 * i_trans.x + cp1 * i_trans.y + cp2 * i_trans.z +cp3;\r
+ return;\r
+ }\r
+ private final NyARDoublePoint3d __modifyMatrix_angle = new NyARDoublePoint3d();\r
+ private final NyARDoubleMatrix34 __modifyMatrix_combo=new NyARDoubleMatrix34();\r
+ private final NyARDoubleMatrix33[] __modifyMatrix_next_rot_matrix=NyARDoubleMatrix33.createArray(27); \r
+ public double modifyMatrix(NyARRotMatrix_ARToolKit io_rot, NyARDoublePoint3d i_trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException\r
+ {\r
+ final NyARDoublePoint3d angle = this.__modifyMatrix_angle;\r
+ final NyARDoubleMatrix34 combo=this.__modifyMatrix_combo;\r
+ final NyARDoubleMatrix33[] next_rot_matrix=this.__modifyMatrix_next_rot_matrix;\r
+ double factor;\r
+ double hx, hy, h, x, y;\r
+ double err, minerr = 0;\r
+ int i,i2;\r
+ int best_idx=0;\r
+ angle.setValue(io_rot.refAngle());// arGetAngle( rot, &a, &b, &c );\r
+ factor = 10.0 * Math.PI / 180.0;\r
+ for (int j = 0; j < 10; j++){\r
+ minerr = 1000000000.0;\r
+ //評価用の角度マップ作成\r
+ createRotationMap(angle,factor,next_rot_matrix);\r
+ //評価して一番宜しいIDを保存\r
+ best_idx=(1+1*3+1*9);\r
+ for(i2=0;i2<27;i2++){\r
+ this.getNewMatrix(next_rot_matrix[i2],i_trans,combo);\r
+ err = 0.0;\r
+ for (i = 0; i < 4; i++) {\r
+ hx = combo.m00 * i_vertex3d[i].x + combo.m01 * i_vertex3d[i].y + combo.m02 * i_vertex3d[i].z + combo.m03;\r
+ hy = combo.m10 * i_vertex3d[i].x + combo.m11 *i_vertex3d[i].y + combo.m12 * i_vertex3d[i].z + combo.m13;\r
+ h = combo.m20 * i_vertex3d[i].x + combo.m21 * i_vertex3d[i].y + combo.m22 * i_vertex3d[i].z + combo.m23;\r
+ x = i_vertex2d[i].x-(hx / h);\r
+ y = i_vertex2d[i].y-(hy / h);\r
+ err += x*x+y*y;\r
+ }\r
+ if (err < minerr){\r
+ minerr = err;\r
+ best_idx=i2;\r
+ }\r
+ \r
+ }\r
+ if (best_idx==(1+1*3+1*9)){\r
+ factor *= 0.5; \r
+ }else{\r
+ angle.z+=factor*(best_idx%3-1);\r
+ angle.y+=factor*((best_idx/3)%3-1);\r
+ angle.x+=factor*((best_idx/9)%3-1); \r
+ }\r
+ }\r
+ io_rot.setAngle(angle.x,angle.y,angle.z);\r
+ /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
+ return minerr / 4;\r
+ }\r
+\r
+\r
+\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.optimize.artoolkit;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.rotmatrix.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+/**\r
+ * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算\r
+ * を繰り返して、変換行列を最適化する。\r
+ *\r
+ */\r
+public class NyARRotMatrixOptimize_O2 implements INyARRotMatrixOptimize\r
+{\r
+ private final NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+ public NyARRotMatrixOptimize_O2(NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+ {\r
+ this._projection_mat_ref=i_projection_mat_ref;\r
+ return;\r
+ }\r
+ private final double[][] __modifyMatrix_double1D = new double[8][3];\r
+ /**\r
+ * arGetRot計算を階層化したModifyMatrix 896\r
+ * \r
+ * @param trans\r
+ * @param i_vertex3d\r
+ * [m][3]\r
+ * @param i_vertex2d\r
+ * [n][2]\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public double modifyMatrix(NyARRotMatrix_ARToolKit io_rot,NyARDoublePoint3d trans, NyARDoublePoint3d[] i_vertex3d, NyARDoublePoint2d[] i_vertex2d) throws NyARException\r
+ {\r
+ double factor;\r
+ double a2, b2, c2;\r
+ double h, x, y;\r
+ double err, minerr = 0;\r
+ int t1, t2, t3;\r
+ int best_idx=0;\r
+\r
+ factor = 10.0 * Math.PI / 180.0;\r
+ double rot0, rot1, rot2;\r
+ double combo00, combo01, combo02, combo03, combo10, combo11, combo12, combo13, combo20, combo21, combo22, combo23;\r
+ double combo02_2, combo02_5, combo02_8, combo02_11;\r
+ double combo22_2, combo22_5, combo22_8, combo22_11;\r
+ double combo12_2, combo12_5, combo12_8, combo12_11;\r
+ // vertex展開\r
+ final double VX00, VX01, VX02, VX10, VX11, VX12, VX20, VX21, VX22, VX30, VX31, VX32;\r
+ VX00 = i_vertex3d[0].x;\r
+ VX01 = i_vertex3d[0].y;\r
+ VX02 = i_vertex3d[0].z;\r
+ VX10 = i_vertex3d[1].x;\r
+ VX11 = i_vertex3d[1].y;\r
+ VX12 = i_vertex3d[1].z;\r
+ VX20 = i_vertex3d[2].x;\r
+ VX21 = i_vertex3d[2].y;\r
+ VX22 = i_vertex3d[2].z;\r
+ VX30 = i_vertex3d[3].x;\r
+ VX31 = i_vertex3d[3].y;\r
+ VX32 = i_vertex3d[3].z;\r
+ final double P2D00, P2D01, P2D10, P2D11, P2D20, P2D21, P2D30, P2D31;\r
+ P2D00 = i_vertex2d[0].x;\r
+ P2D01 = i_vertex2d[0].y;\r
+ P2D10 = i_vertex2d[1].x;\r
+ P2D11 = i_vertex2d[1].y;\r
+ P2D20 = i_vertex2d[2].x;\r
+ P2D21 = i_vertex2d[2].y;\r
+ P2D30 = i_vertex2d[3].x;\r
+ P2D31 = i_vertex2d[3].y;\r
+ final NyARPerspectiveProjectionMatrix prjmat = this._projection_mat_ref;\r
+ final double CP0 = prjmat.m00,CP1 = prjmat.m01,CP2 = prjmat.m02,CP4 = prjmat.m10,CP5 = prjmat.m11,CP6 = prjmat.m12,CP8 = prjmat.m20,CP9 = prjmat.m21,CP10 = prjmat.m22;\r
+ combo03 = CP0 * trans.x + CP1 * trans.y + CP2 * trans.z + prjmat.m03;\r
+ combo13 = CP4 * trans.x + CP5 * trans.y + CP6 * trans.z + prjmat.m13;\r
+ combo23 = CP8 * trans.x + CP9 * trans.y + CP10 * trans.z + prjmat.m23;\r
+ double CACA, SASA, SACA, CA, SA;\r
+ double CACACB, SACACB, SASACB, CASB, SASB;\r
+ double SACASC, SACACBSC, SACACBCC, SACACC;\r
+ final double[][] double1D = this.__modifyMatrix_double1D;\r
+\r
+ final double[] a_factor = double1D[1];\r
+ final double[] sinb = double1D[2];\r
+ final double[] cosb = double1D[3];\r
+ final double[] b_factor = double1D[4];\r
+ final double[] sinc = double1D[5];\r
+ final double[] cosc = double1D[6];\r
+ final double[] c_factor = double1D[7];\r
+ double w, w2;\r
+ double wsin, wcos;\r
+ \r
+ final NyARDoublePoint3d angle = io_rot.refAngle();\r
+ a2 = angle.x;\r
+ b2 = angle.y;\r
+ c2 = angle.z;\r
+\r
+ // comboの3行目を先に計算\r
+ for (int i = 0; i < 10; i++) {\r
+ minerr = 1000000000.0;\r
+ // sin-cosテーブルを計算(これが外に出せるとは…。)\r
+ for (int j = 0; j < 3; j++) {\r
+ w2 = factor * (j - 1);\r
+ w = a2 + w2;\r
+ a_factor[j] = w;\r
+ w = b2 + w2;\r
+ b_factor[j] = w;\r
+ sinb[j] = Math.sin(w);\r
+ cosb[j] = Math.cos(w);\r
+ w = c2 + w2;\r
+ c_factor[j] = w;\r
+ sinc[j] = Math.sin(w);\r
+ cosc[j] = Math.cos(w);\r
+ }\r
+ //\r
+ for (t1 = 0; t1 < 3; t1++) {\r
+ SA = Math.sin(a_factor[t1]);\r
+ CA = Math.cos(a_factor[t1]);\r
+ // Optimize\r
+ CACA = CA * CA;\r
+ SASA = SA * SA;\r
+ SACA = SA * CA;\r
+ for (t2 = 0; t2 < 3; t2++) {\r
+ wsin = sinb[t2];\r
+ wcos = cosb[t2];\r
+ CACACB = CACA * wcos;\r
+ SACACB = SACA * wcos;\r
+ SASACB = SASA * wcos;\r
+ CASB = CA * wsin;\r
+ SASB = SA * wsin;\r
+ // comboの計算1\r
+ combo02 = CP0 * CASB + CP1 * SASB + CP2 * wcos;\r
+ combo12 = CP4 * CASB + CP5 * SASB + CP6 * wcos;\r
+ combo22 = CP8 * CASB + CP9 * SASB + CP10 * wcos;\r
+\r
+ combo02_2 = combo02 * VX02 + combo03;\r
+ combo02_5 = combo02 * VX12 + combo03;\r
+ combo02_8 = combo02 * VX22 + combo03;\r
+ combo02_11 = combo02 * VX32 + combo03;\r
+ combo12_2 = combo12 * VX02 + combo13;\r
+ combo12_5 = combo12 * VX12 + combo13;\r
+ combo12_8 = combo12 * VX22 + combo13;\r
+ combo12_11 = combo12 * VX32 + combo13;\r
+ combo22_2 = combo22 * VX02 + combo23;\r
+ combo22_5 = combo22 * VX12 + combo23;\r
+ combo22_8 = combo22 * VX22 + combo23;\r
+ combo22_11 = combo22 * VX32 + combo23;\r
+ for (t3 = 0; t3 < 3; t3++) {\r
+ wsin = sinc[t3];\r
+ wcos = cosc[t3];\r
+ SACASC = SACA * wsin;\r
+ SACACC = SACA * wcos;\r
+ SACACBSC = SACACB * wsin;\r
+ SACACBCC = SACACB * wcos;\r
+\r
+ rot0 = CACACB * wcos + SASA * wcos + SACACBSC - SACASC;\r
+ rot1 = SACACBCC - SACACC + SASACB * wsin + CACA * wsin;\r
+ rot2 = -CASB * wcos - SASB * wsin;\r
+ combo00 = CP0 * rot0 + CP1 * rot1 + CP2 * rot2;\r
+ combo10 = CP4 * rot0 + CP5 * rot1 + CP6 * rot2;\r
+ combo20 = CP8 * rot0 + CP9 * rot1 + CP10 * rot2;\r
+\r
+ rot0 = -CACACB * wsin - SASA * wsin + SACACBCC - SACACC;\r
+ rot1 = -SACACBSC + SACASC + SASACB * wcos + CACA * wcos;\r
+ rot2 = CASB * wsin - SASB * wcos;\r
+ combo01 = CP0 * rot0 + CP1 * rot1 + CP2 * rot2;\r
+ combo11 = CP4 * rot0 + CP5 * rot1 + CP6 * rot2;\r
+ combo21 = CP8 * rot0 + CP9 * rot1 + CP10 * rot2;\r
+ //\r
+ err = 0.0;\r
+ h = combo20 * VX00 + combo21 * VX01 + combo22_2;\r
+ x = P2D00 - (combo00 * VX00 + combo01 * VX01 + combo02_2) / h;\r
+ y = P2D01 - (combo10 * VX00 + combo11 * VX01 + combo12_2) / h;\r
+ err += x * x + y * y;\r
+ h = combo20 * VX10 + combo21 * VX11 + combo22_5;\r
+ x = P2D10 - (combo00 * VX10 + combo01 * VX11 + combo02_5) / h;\r
+ y = P2D11 - (combo10 * VX10 + combo11 * VX11 + combo12_5) / h;\r
+ err += x * x + y * y;\r
+ h = combo20 * VX20 + combo21 * VX21 + combo22_8;\r
+ x = P2D20 - (combo00 * VX20 + combo01 * VX21 + combo02_8) / h;\r
+ y = P2D21 - (combo10 * VX20 + combo11 * VX21 + combo12_8) / h;\r
+ err += x * x + y * y;\r
+ h = combo20 * VX30 + combo21 * VX31 + combo22_11;\r
+ x = P2D30 - (combo00 * VX30 + combo01 * VX31 + combo02_11) / h;\r
+ y = P2D31 - (combo10 * VX30 + combo11 * VX31 + combo12_11) / h;\r
+ err += x * x + y * y;\r
+ if (err < minerr) {\r
+ minerr = err;\r
+ a2 = a_factor[t1];\r
+ b2 = b_factor[t2];\r
+ c2 = c_factor[t3];\r
+ best_idx=t1+t2*3+t3*9;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (best_idx==(1+3+9)) {\r
+ factor *= 0.5;\r
+ }\r
+ }\r
+ io_rot.setAngle(a2, b2, c2);\r
+ /* printf("factor = %10.5f\n", factor*180.0/MD_PI); */\r
+ return minerr /4;\r
+ } \r
+ \r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.rotmatrix;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARPerspectiveProjectionMatrix;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix33;\r
+/**\r
+ * 回転行列計算用の、3x3行列\r
+ *\r
+ */\r
+public class NyARRotMatrix extends NyARDoubleMatrix33\r
+{\r
+ /**\r
+ * インスタンスを準備します。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARRotMatrix(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException\r
+ {\r
+ this.__initRot_vec1=new NyARRotVector(i_matrix);\r
+ this.__initRot_vec2=new NyARRotVector(i_matrix);\r
+ return;\r
+ }\r
+ final private NyARRotVector __initRot_vec1;\r
+ final private NyARRotVector __initRot_vec2;\r
+ /**\r
+ * NyARTransMatResultの内容からNyARRotMatrixを復元します。\r
+ * @param i_prev_result\r
+ */\r
+ public final void initRotByPrevResult(NyARTransMatResult i_prev_result)\r
+ {\r
+\r
+ this.m00=i_prev_result.m00;\r
+ this.m01=i_prev_result.m01;\r
+ this.m02=i_prev_result.m02;\r
+\r
+ this.m10=i_prev_result.m10;\r
+ this.m11=i_prev_result.m11;\r
+ this.m12=i_prev_result.m12;\r
+\r
+ this.m20=i_prev_result.m20;\r
+ this.m21=i_prev_result.m21;\r
+ this.m22=i_prev_result.m22;\r
+ return;\r
+ } \r
+ /**\r
+ * \r
+ * @param i_linear\r
+ * @param i_sqvertex\r
+ * @throws NyARException\r
+ */\r
+ public void initRotBySquare(final NyARLinear[] i_linear,final NyARDoublePoint2d[] i_sqvertex) throws NyARException\r
+ {\r
+ final NyARRotVector vec1=this.__initRot_vec1;\r
+ final NyARRotVector vec2=this.__initRot_vec2;\r
+\r
+ //向かい合った辺から、2本のベクトルを計算\r
+ \r
+ //軸1\r
+ vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]);\r
+ vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]);\r
+\r
+ //軸2\r
+ vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]);\r
+ vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]);\r
+\r
+ //回転の最適化?\r
+ NyARRotVector.checkRotation(vec1,vec2);\r
+\r
+ this.m00 =vec1.v1;\r
+ this.m10 =vec1.v2;\r
+ this.m20 =vec1.v3;\r
+ this.m01 =vec2.v1;\r
+ this.m11 =vec2.v2;\r
+ this.m21 =vec2.v3;\r
+ \r
+ //最後の軸を計算\r
+ final double w02 = vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2;\r
+ final double w12 = vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3;\r
+ final double w22 = vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1;\r
+ final double w = Math.sqrt(w02 * w02 + w12 * w12 + w22 * w22);\r
+ this.m02 = w02/w;\r
+ this.m12 = w12/w;\r
+ this.m22 = w22/w;\r
+ return;\r
+ }\r
+ /**\r
+ * i_in_pointを変換行列で座標変換する。\r
+ * @param i_in_point\r
+ * @param i_out_point\r
+ */\r
+ public final void getPoint3d(final NyARDoublePoint3d i_in_point,final NyARDoublePoint3d i_out_point)\r
+ {\r
+ final double x=i_in_point.x;\r
+ final double y=i_in_point.y;\r
+ final double z=i_in_point.z;\r
+ i_out_point.x=this.m00 * x + this.m01 * y + this.m02 * z;\r
+ i_out_point.y=this.m10 * x + this.m11 * y + this.m12 * z;\r
+ i_out_point.z=this.m20 * x + this.m21 * y + this.m22 * z;\r
+ return;\r
+ }\r
+ /**\r
+ * 複数の頂点を一括して変換する\r
+ * @param i_in_point\r
+ * @param i_out_point\r
+ * @param i_number_of_vertex\r
+ */\r
+ public final void getPoint3dBatch(final NyARDoublePoint3d[] i_in_point,NyARDoublePoint3d[] i_out_point,int i_number_of_vertex)\r
+ {\r
+ for(int i=i_number_of_vertex-1;i>=0;i--){\r
+ final NyARDoublePoint3d out_ptr=i_out_point[i];\r
+ final NyARDoublePoint3d in_ptr=i_in_point[i];\r
+ final double x=in_ptr.x;\r
+ final double y=in_ptr.y;\r
+ final double z=in_ptr.z;\r
+ out_ptr.x=this.m00 * x + this.m01 * y + this.m02 * z;\r
+ out_ptr.y=this.m10 * x + this.m11 * y + this.m12 * z;\r
+ out_ptr.z=this.m20 * x + this.m21 * y + this.m22 * z;\r
+ }\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.rotmatrix;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+/**\r
+ * 回転行列計算用の、3x3行列\r
+ *\r
+ */\r
+public class NyARRotMatrix_ARToolKit extends NyARRotMatrix\r
+{ \r
+ /**\r
+ * インスタンスを準備します。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARRotMatrix_ARToolKit(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException\r
+ {\r
+ super(i_matrix);\r
+ this._angle=new NyARDoublePoint3d();\r
+ return;\r
+ }\r
+ final protected NyARDoublePoint3d _angle;\r
+ \r
+\r
+ \r
+ public final void initRotBySquare(final NyARLinear[] i_linear,final NyARDoublePoint2d[] i_sqvertex) throws NyARException\r
+ {\r
+ super.initRotBySquare(i_linear,i_sqvertex);\r
+ //Matrixからangleをロード\r
+ this.updateAngleFromMatrix();\r
+ return;\r
+ }\r
+ public final NyARDoublePoint3d refAngle()\r
+ {\r
+ return this._angle;\r
+ }\r
+ /**\r
+ * 回転角から回転行列を計算してセットします。\r
+ * @param i_x\r
+ * @param i_y\r
+ * @param i_z\r
+ */\r
+ public void setAngle(final double i_x, final double i_y, final double i_z)\r
+ {\r
+ final double sina = Math.sin(i_x);\r
+ final double cosa = Math.cos(i_x);\r
+ final double sinb = Math.sin(i_y);\r
+ final double cosb = Math.cos(i_y);\r
+ final double sinc = Math.sin(i_z);\r
+ final double cosc = Math.cos(i_z);\r
+ // Optimize\r
+ final double CACA = cosa * cosa;\r
+ final double SASA = sina * sina;\r
+ final double SACA = sina * cosa;\r
+ final double SASB = sina * sinb;\r
+ final double CASB = cosa * sinb;\r
+ final double SACACB = SACA * cosb;\r
+\r
+ this.m00 = CACA * cosb * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;\r
+ this.m01 = -CACA * cosb * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;\r
+ this.m02 = CASB;\r
+ this.m10 = SACACB * cosc - SACA * cosc + SASA * cosb * sinc + CACA * sinc;\r
+ this.m11 = -SACACB * sinc + SACA * sinc + SASA * cosb * cosc + CACA * cosc;\r
+ this.m12 = SASB;\r
+ this.m20 = -CASB * cosc - SASB * sinc;\r
+ this.m21 = CASB * sinc - SASB * cosc;\r
+ this.m22 = cosb;\r
+ updateAngleFromMatrix();\r
+ return;\r
+ }\r
+ /**\r
+ * 現在のMatrixからangkeを復元する。\r
+ * @param o_angle\r
+ */\r
+ private final void updateAngleFromMatrix()\r
+ {\r
+ double a,b,c;\r
+ double sina, cosa, sinb,cosb,sinc, cosc;\r
+ \r
+ if (this.m22 > 1.0) {// <Optimize/>if( rot[2][2] > 1.0 ) {\r
+ cosb = 1.0;// <Optimize/>rot[2][2] = 1.0;\r
+ } else if (this.m22 < -1.0) {// <Optimize/>}else if( rot[2][2] < -1.0 ) {\r
+ cosb = -1.0;// <Optimize/>rot[2][2] = -1.0;\r
+ }else{\r
+ cosb =this.m22;// <Optimize/>cosb = rot[2][2];\r
+ }\r
+ b = Math.acos(cosb);\r
+ sinb =Math.sin(b);\r
+ final double rot02=this.m02;\r
+ final double rot12=this.m12;\r
+ if (b >= 0.000001 || b <= -0.000001) {\r
+ cosa = rot02 / sinb;// <Optimize/>cosa = rot[0][2] / sinb;\r
+ sina = rot12 / sinb;// <Optimize/>sina = rot[1][2] / sinb;\r
+ if (cosa > 1.0) {\r
+ cosa = 1.0;\r
+ sina = 0.0;\r
+ }\r
+ if (cosa < -1.0) {\r
+ cosa = -1.0;\r
+ sina = 0.0;\r
+ }\r
+ if (sina > 1.0) {\r
+ sina = 1.0;\r
+ cosa = 0.0;\r
+ }\r
+ if (sina < -1.0) {\r
+ sina = -1.0;\r
+ cosa = 0.0;\r
+ }\r
+ a = Math.acos(cosa);\r
+ if (sina < 0) {\r
+ a = -a;\r
+ }\r
+ final double tmp = (rot02 * rot02 + rot12 * rot12);\r
+ sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp;\r
+ cosc = -(rot02 * this.m20 + rot12 * this.m21) / tmp;\r
+\r
+ if (cosc > 1.0) {\r
+ cosc = 1.0;\r
+ sinc = 0.0;\r
+ }\r
+ if (cosc < -1.0) {\r
+ cosc = -1.0;\r
+ sinc = 0.0;\r
+ }\r
+ if (sinc > 1.0) {\r
+ sinc = 1.0;\r
+ cosc = 0.0;\r
+ }\r
+ if (sinc < -1.0) {\r
+ sinc = -1.0;\r
+ cosc = 0.0;\r
+ }\r
+ c = Math.acos(cosc);\r
+ if (sinc < 0) {\r
+ c = -c;\r
+ }\r
+ } else {\r
+ a = b = 0.0;\r
+ cosa = cosb = 1.0;\r
+ sina = sinb = 0.0;\r
+ cosc=this.m00;//cosc = rot[0];// <Optimize/>cosc = rot[0][0];\r
+ sinc=this.m01;//sinc = rot[1];// <Optimize/>sinc = rot[1][0];\r
+ if (cosc > 1.0) {\r
+ cosc = 1.0;\r
+ sinc = 0.0;\r
+ }\r
+ if (cosc < -1.0) {\r
+ cosc = -1.0;\r
+ sinc = 0.0;\r
+ }\r
+ if (sinc > 1.0) {\r
+ sinc = 1.0;\r
+ cosc = 0.0;\r
+ }\r
+ if (sinc < -1.0) {\r
+ sinc = -1.0;\r
+ cosc = 0.0;\r
+ }\r
+ c = Math.acos(cosc);\r
+ if (sinc < 0) {\r
+ c = -c;\r
+ }\r
+ }\r
+ //angleの更新\r
+ this._angle.x = a;// wa.value=a;//*wa = a;\r
+ this._angle.y = b;// wb.value=b;//*wb = b;\r
+ this._angle.z = c;// wc.value=c;//*wc = c;\r
+ return;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.rotmatrix;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+/**\r
+ * 回転行列計算用の、3x3行列\r
+ * 計算方法はARToolKitと同じだが、ARToolKitにある不要な行列から角度を逆算する\r
+ * 処理を省略しているため、下位12桁目の計算値が異なる。\r
+ *\r
+ */\r
+public class NyARRotMatrix_ARToolKit_O2 extends NyARRotMatrix_ARToolKit\r
+{ \r
+ /**\r
+ * インスタンスを準備します。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARRotMatrix_ARToolKit_O2(NyARPerspectiveProjectionMatrix i_matrix) throws NyARException\r
+ {\r
+ super(i_matrix);\r
+ return;\r
+ }\r
+ public final void setAngle(final double i_x, final double i_y, final double i_z)\r
+ {\r
+ final double sina = Math.sin(i_x);\r
+ final double cosa = Math.cos(i_x);\r
+ final double sinb = Math.sin(i_y);\r
+ final double cosb = Math.cos(i_y);\r
+ final double sinc = Math.sin(i_z);\r
+ final double cosc = Math.cos(i_z);\r
+ // Optimize\r
+ final double CACA = cosa * cosa;\r
+ final double SASA = sina * sina;\r
+ final double SACA = sina * cosa;\r
+ final double SASB = sina * sinb;\r
+ final double CASB = cosa * sinb;\r
+ final double SACACB = SACA * cosb;\r
+\r
+ this.m00 = CACA * cosb * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;\r
+ this.m01 = -CACA * cosb * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;\r
+ this.m02 = CASB;\r
+ this.m10 = SACACB * cosc - SACA * cosc + SASA * cosb * sinc + CACA * sinc;\r
+ this.m11 = -SACACB * sinc + SACA * sinc + SASA * cosb * cosc + CACA * cosc;\r
+ this.m12 = SASB;\r
+ this.m20 = -CASB * cosc - SASB * sinc;\r
+ this.m21 = CASB * sinc - SASB * cosc;\r
+ this.m22 = cosb;\r
+ //angleを逆計算せずに直接代入\r
+ this._angle.x=i_x;\r
+ this._angle.y=i_y;\r
+ this._angle.z=i_z;\r
+ return;\r
+ }\r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.rotmatrix;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+\r
+public class NyARRotVector\r
+{\r
+\r
+ //publicメンバ達\r
+ public double v1;\r
+\r
+ public double v2;\r
+\r
+ public double v3;\r
+\r
+ //privateメンバ達\r
+ \r
+ private NyARPerspectiveProjectionMatrix _projection_mat_ref;\r
+\r
+ private double[][] _inv_cpara_array_ref;\r
+\r
+ public NyARRotVector(NyARPerspectiveProjectionMatrix i_cmat) throws NyARException\r
+ {\r
+ NyARMat mat_a = new NyARMat(3, 3);\r
+ double[][] a_array = mat_a.getArray();\r
+ \r
+ a_array[0][0] =i_cmat.m00;\r
+ a_array[0][1] =i_cmat.m01;\r
+ a_array[0][2] =i_cmat.m02;\r
+ a_array[1][0] =i_cmat.m10;\r
+ a_array[1][1] =i_cmat.m11;\r
+ a_array[1][2] =i_cmat.m12;\r
+ a_array[2][0] =i_cmat.m20;\r
+ a_array[2][1] =i_cmat.m21;\r
+ a_array[2][2] =i_cmat.m22;\r
+ \r
+ mat_a.matrixSelfInv();\r
+ this._projection_mat_ref = i_cmat;\r
+ this._inv_cpara_array_ref = mat_a.getArray();\r
+ //GCない言語のときは、ここで配列の所有権委譲してね!\r
+ }\r
+\r
+ /**\r
+ * 2直線に直交するベクトルを計算する・・・だと思う。\r
+ * @param i_linear1\r
+ * @param i_linear2\r
+ */\r
+ public void exteriorProductFromLinear(NyARLinear i_linear1, NyARLinear i_linear2)\r
+ {\r
+ //1行目\r
+ final NyARPerspectiveProjectionMatrix cmat= this._projection_mat_ref;\r
+ final double w1 = i_linear1.dy * i_linear2.dx - i_linear2.dy * i_linear1.dx;\r
+ final double w2 = i_linear1.dx * i_linear2.c - i_linear2.dx * i_linear1.c;\r
+ final double w3 = i_linear1.c * i_linear2.dy - i_linear2.c * i_linear1.dy;\r
+\r
+ final double m0 = w1 * (cmat.m01 * cmat.m12 - cmat.m02 * cmat.m11) + w2 * cmat.m11 - w3 * cmat.m01;//w1 * (cpara[0 * 4 + 1] * cpara[1 * 4 + 2] - cpara[0 * 4 + 2] * cpara[1 * 4 + 1]) + w2 * cpara[1 * 4 + 1] - w3 * cpara[0 * 4 + 1];\r
+ final double m1 = -w1 * cmat.m00 * cmat.m12 + w3 * cmat.m00;//-w1 * cpara[0 * 4 + 0] * cpara[1 * 4 + 2] + w3 * cpara[0 * 4 + 0];\r
+ final double m2 = w1 * cmat.m00 * cmat.m11;//w1 * cpara[0 * 4 + 0] * cpara[1 * 4 + 1];\r
+ final double w = Math.sqrt(m0 * m0 + m1 * m1 + m2 * m2);\r
+ this.v1 = m0 / w;\r
+ this.v2 = m1 / w;\r
+ this.v3 = m2 / w;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * static int check_dir( double dir[3], double st[2], double ed[2],double cpara[3][4] ) Optimize:STEP[526->468]\r
+ * ベクトルの開始/終了座標を指定して、ベクトルの方向を調整する。\r
+ * @param i_start_vertex\r
+ * @param i_end_vertex\r
+ * @param cpara\r
+ */\r
+ public void checkVectorByVertex(final NyARDoublePoint2d i_start_vertex, final NyARDoublePoint2d i_end_vertex) throws NyARException\r
+ {\r
+ double h;\r
+ final double[][] inv_cpara = this._inv_cpara_array_ref;\r
+ //final double[] world = __checkVectorByVertex_world;// [2][3];\r
+ final double world0 = inv_cpara[0][0] * i_start_vertex.x * 10.0 + inv_cpara[0][1] * i_start_vertex.y * 10.0 + inv_cpara[0][2] * 10.0;// mat_a->m[0]*st[0]*10.0+\r
+ final double world1 = inv_cpara[1][0] * i_start_vertex.x * 10.0 + inv_cpara[1][1] * i_start_vertex.y * 10.0 + inv_cpara[1][2] * 10.0;// mat_a->m[3]*st[0]*10.0+\r
+ final double world2 = inv_cpara[2][0] * i_start_vertex.x * 10.0 + inv_cpara[2][1] * i_start_vertex.y * 10.0 + inv_cpara[2][2] * 10.0;// mat_a->m[6]*st[0]*10.0+\r
+ final double world3 = world0 + this.v1;\r
+ final double world4 = world1 + this.v2;\r
+ final double world5 = world2 + this.v3;\r
+ // </Optimize>\r
+\r
+ //final double[] camera = __checkVectorByVertex_camera;// [2][2];\r
+ final NyARPerspectiveProjectionMatrix cmat= this._projection_mat_ref;\r
+ //h = cpara[2 * 4 + 0] * world0 + cpara[2 * 4 + 1] * world1 + cpara[2 * 4 + 2] * world2;\r
+ h = cmat.m20 * world0 + cmat.m21 * world1 + cmat.m22 * world2;\r
+ if (h == 0.0) {\r
+ throw new NyARException();\r
+ }\r
+ //final double camera0 = (cpara[0 * 4 + 0] * world0 + cpara[0 * 4 + 1] * world1 + cpara[0 * 4 + 2] * world2) / h;\r
+ //final double camera1 = (cpara[1 * 4 + 0] * world0 + cpara[1 * 4 + 1] * world1 + cpara[1 * 4 + 2] * world2) / h;\r
+ final double camera0 = (cmat.m00 * world0 + cmat.m01 * world1 + cmat.m02 * world2) / h;\r
+ final double camera1 = (cmat.m10 * world0 + cmat.m11 * world1 + cmat.m12 * world2) / h;\r
+\r
+ //h = cpara[2 * 4 + 0] * world3 + cpara[2 * 4 + 1] * world4 + cpara[2 * 4 + 2] * world5;\r
+ h = cmat.m20 * world3 + cmat.m21 * world4 + cmat.m22 * world5;\r
+ if (h == 0.0) {\r
+ throw new NyARException();\r
+ }\r
+ //final double camera2 = (cpara[0 * 4 + 0] * world3 + cpara[0 * 4 + 1] * world4 + cpara[0 * 4 + 2] * world5) / h;\r
+ //final double camera3 = (cpara[1 * 4 + 0] * world3 + cpara[1 * 4 + 1] * world4 + cpara[1 * 4 + 2] * world5) / h;\r
+ final double camera2 = (cmat.m00 * world3 + cmat.m01 * world4 + cmat.m02 * world5) / h;\r
+ final double camera3 = (cmat.m10 * world3 + cmat.m11 * world4 + cmat.m12 * world5) / h;\r
+\r
+ final double v = (i_end_vertex.x - i_start_vertex.x) * (camera2 - camera0) + (i_end_vertex.y - i_start_vertex.y) * (camera3 - camera1);\r
+ if (v < 0) {\r
+ this.v1 = -this.v1;\r
+ this.v2 = -this.v2;\r
+ this.v3 = -this.v3;\r
+ }\r
+ }\r
+ /**\r
+ * int check_rotation( double rot[2][3] )\r
+ * 2つのベクトル引数の調整をする?\r
+ * @param i_r\r
+ * @throws NyARException\r
+ */\r
+\r
+ public final static void checkRotation(NyARRotVector io_vec1, NyARRotVector io_vec2) throws NyARException\r
+ {\r
+ double w;\r
+ int f;\r
+\r
+ double vec10 = io_vec1.v1;\r
+ double vec11 = io_vec1.v2;\r
+ double vec12 = io_vec1.v3;\r
+ double vec20 = io_vec2.v1;\r
+ double vec21 = io_vec2.v2;\r
+ double vec22 = io_vec2.v3;\r
+ \r
+ double vec30 = vec11 * vec22 - vec12 * vec21;\r
+ double vec31 = vec12 * vec20 - vec10 * vec22;\r
+ double vec32 = vec10 * vec21 - vec11 * vec20;\r
+ w = Math.sqrt(vec30 * vec30 + vec31 * vec31 + vec32 * vec32);\r
+ if (w == 0.0) {\r
+ throw new NyARException();\r
+ }\r
+ vec30 /= w;\r
+ vec31 /= w;\r
+ vec32 /= w;\r
+\r
+ double cb = vec10 * vec20 + vec11 * vec21 + vec12 * vec22;\r
+ if (cb < 0){\r
+ cb=-cb;//cb *= -1.0; \r
+ }\r
+ final double ca = (Math.sqrt(cb + 1.0) + Math.sqrt(1.0 - cb)) * 0.5;\r
+\r
+ if (vec31 * vec10 - vec11 * vec30 != 0.0) {\r
+ f = 0;\r
+ } else {\r
+ if (vec32 * vec10 - vec12 * vec30 != 0.0) {\r
+ w = vec11;vec11 = vec12;vec12 = w;\r
+ w = vec31;vec31 = vec32;vec32 = w;\r
+ f = 1;\r
+ } else {\r
+ w = vec10;vec10 = vec12;vec12 = w;\r
+ w = vec30;vec30 = vec32;vec32 = w;\r
+ f = 2;\r
+ }\r
+ }\r
+ if (vec31 * vec10 - vec11 * vec30 == 0.0) {\r
+ throw new NyARException();\r
+ }\r
+ \r
+ double k1,k2,k3,k4;\r
+ double a, b, c, d;\r
+ double p1, q1, r1;\r
+ double p2, q2, r2;\r
+ double p3, q3, r3;\r
+ double p4, q4, r4; \r
+ \r
+ \r
+ k1 = (vec11 * vec32 - vec31 * vec12) / (vec31 * vec10 - vec11 * vec30);\r
+ k2 = (vec31 * ca) / (vec31 * vec10 - vec11 * vec30);\r
+ k3 = (vec10 * vec32 - vec30 * vec12) / (vec30 * vec11 - vec10 * vec31);\r
+ k4 = (vec30 * ca) / (vec30 * vec11 - vec10 * vec31);\r
+\r
+ a = k1 * k1 + k3 * k3 + 1;\r
+ b = k1 * k2 + k3 * k4;\r
+ c = k2 * k2 + k4 * k4 - 1;\r
+\r
+ d = b * b - a * c;\r
+ if (d < 0) {\r
+ throw new NyARException();\r
+ }\r
+ r1 = (-b + Math.sqrt(d)) / a;\r
+ p1 = k1 * r1 + k2;\r
+ q1 = k3 * r1 + k4;\r
+ r2 = (-b - Math.sqrt(d)) / a;\r
+ p2 = k1 * r2 + k2;\r
+ q2 = k3 * r2 + k4;\r
+ if (f == 1) {\r
+ w = q1;q1 = r1;r1 = w;\r
+ w = q2;q2 = r2;r2 = w;\r
+ w = vec11;vec11 = vec12;vec12 = w;\r
+ w = vec31;vec31 = vec32;vec32 = w;\r
+ f = 0;\r
+ }\r
+ if (f == 2) {\r
+ w = p1;p1 = r1;r1 = w;\r
+ w = p2;p2 = r2;r2 = w;\r
+ w = vec10;vec10 = vec12;vec12 = w;\r
+ w = vec30;vec30 = vec32;vec32 = w;\r
+ f = 0;\r
+ }\r
+\r
+ if (vec31 * vec20 - vec21 * vec30 != 0.0) {\r
+ f = 0;\r
+ } else {\r
+ if (vec32 * vec20 - vec22 * vec30 != 0.0) {\r
+ w = vec21;vec21 = vec22;vec22 = w;\r
+ w = vec31;vec31 = vec32;vec32 = w;\r
+ f = 1;\r
+ } else {\r
+ w = vec20;vec20 = vec22;vec22 = w;\r
+ w = vec30;vec30 = vec32;vec32 = w;\r
+ f = 2;\r
+ }\r
+ }\r
+ if (vec31 * vec20 - vec21 * vec30 == 0.0) {\r
+ throw new NyARException();\r
+ }\r
+ k1 = (vec21 * vec32 - vec31 * vec22) / (vec31 * vec20 - vec21 * vec30);\r
+ k2 = (vec31 * ca) / (vec31 * vec20 - vec21 * vec30);\r
+ k3 = (vec20 * vec32 - vec30 * vec22) / (vec30 * vec21 - vec20 * vec31);\r
+ k4 = (vec30 * ca) / (vec30 * vec21 - vec20 * vec31);\r
+\r
+ a = k1 * k1 + k3 * k3 + 1;\r
+ b = k1 * k2 + k3 * k4;\r
+ c = k2 * k2 + k4 * k4 - 1;\r
+\r
+ d = b * b - a * c;\r
+ if (d < 0) {\r
+ throw new NyARException();\r
+ }\r
+ r3 = (-b + Math.sqrt(d)) / a;\r
+ p3 = k1 * r3 + k2;\r
+ q3 = k3 * r3 + k4;\r
+ r4 = (-b - Math.sqrt(d)) / a;\r
+ p4 = k1 * r4 + k2;\r
+ q4 = k3 * r4 + k4;\r
+ if (f == 1) {\r
+ w = q3;q3 = r3;r3 = w;\r
+ w = q4;q4 = r4;r4 = w;\r
+ w = vec21;vec21 = vec22;vec22 = w;\r
+ w = vec31;vec31 = vec32;vec32 = w;\r
+ f = 0;\r
+ }\r
+ if (f == 2) {\r
+ w = p3;p3 = r3;r3 = w;\r
+ w = p4;p4 = r4;r4 = w;\r
+ w = vec20;vec20 = vec22;vec22 = w;\r
+ w = vec30;vec30 = vec32;vec32 = w;\r
+ f = 0;\r
+ }\r
+\r
+ double e1 = p1 * p3 + q1 * q3 + r1 * r3;\r
+ if (e1 < 0) {\r
+ e1 = -e1;\r
+ }\r
+ double e2 = p1 * p4 + q1 * q4 + r1 * r4;\r
+ if (e2 < 0) {\r
+ e2 = -e2;\r
+ }\r
+ double e3 = p2 * p3 + q2 * q3 + r2 * r3;\r
+ if (e3 < 0) {\r
+ e3 = -e3;\r
+ }\r
+ double e4 = p2 * p4 + q2 * q4 + r2 * r4;\r
+ if (e4 < 0) {\r
+ e4 = -e4;\r
+ }\r
+ if (e1 < e2) {\r
+ if (e1 < e3) {\r
+ if (e1 < e4) {\r
+ io_vec1.v1 = p1;\r
+ io_vec1.v2 = q1;\r
+ io_vec1.v3 = r1;\r
+ io_vec2.v1 = p3;\r
+ io_vec2.v2 = q3;\r
+ io_vec2.v3 = r3;\r
+ } else {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p4;\r
+ io_vec2.v2 = q4;\r
+ io_vec2.v3 = r4;\r
+ }\r
+ } else {\r
+ if (e3 < e4) {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p3;\r
+ io_vec2.v2 = q3;\r
+ io_vec2.v3 = r3;\r
+ } else {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p4;\r
+ io_vec2.v2 = q4;\r
+ io_vec2.v3 = r4;\r
+ }\r
+ }\r
+ } else {\r
+ if (e2 < e3) {\r
+ if (e2 < e4) {\r
+ io_vec1.v1 = p1;\r
+ io_vec1.v2 = q1;\r
+ io_vec1.v3 = r1;\r
+ io_vec2.v1 = p4;\r
+ io_vec2.v2 = q4;\r
+ io_vec2.v3 = r4;\r
+ } else {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p4;\r
+ io_vec2.v2 = q4;\r
+ io_vec2.v3 = r4;\r
+ }\r
+ } else {\r
+ if (e3 < e4) {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p3;\r
+ io_vec2.v2 = q3;\r
+ io_vec2.v3 = r3;\r
+ } else {\r
+ io_vec1.v1 = p2;\r
+ io_vec1.v2 = q2;\r
+ io_vec1.v3 = r2;\r
+ io_vec2.v1 = p4;\r
+ io_vec2.v2 = q4;\r
+ io_vec2.v3 = r4;\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.solver;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+\r
+/**\r
+ * 並進ベクトル[T]を3次元座標[b]と基点の回転済行列[M]から計算するインタフェイスです。\r
+ * [M][T]=[b]\r
+ *\r
+ */\r
+public interface INyARTransportVectorSolver\r
+{\r
+ public void set2dVertex(NyARDoublePoint2d[] i_ref_vertex_2d,int i_number_of_vertex) throws NyARException;\r
+ /**\r
+ * 画面座標群と3次元座標群から、平行移動量を計算します。\r
+ * 2d座標系は、直前に実行したset2dVertexのものを使用します。\r
+ * @param i_vertex_2d\r
+ * 直前のset2dVertexコールで指定したものと同じものを指定してください。\r
+ * @param i_vertex3d\r
+ * 3次元空間の座標群を設定します。頂点の順番は、画面座標群と同じ順序で格納してください。\r
+ * @param o_transfer\r
+ * @throws NyARException\r
+ */\r
+ public void solveTransportVector(NyARDoublePoint3d[] i_vertex3d,NyARDoublePoint3d o_transfer) throws NyARException;\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.solver;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARPerspectiveProjectionMatrix;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 並進ベクトル[T]を3次元座標[b]と基点の回転済行列[M]から計算します。\r
+ * \r
+ * アルゴリズムは、ARToolKit 拡張現実プログラミング入門 の、P207のものです。\r
+ * \r
+ * 計算手順\r
+ * [A]*[T]=bを、[A]T*[A]*[T]=[A]T*[b]にする。\r
+ * set2dVertexで[A]T*[A]=[M]を計算して、Aの3列目の情報だけ保存しておく。\r
+ * getTransportVectorで[M]*[T]=[A]T*[b]を連立方程式で解いて、[T]を得る。\r
+ */\r
+public class NyARTransportVectorSolver implements INyARTransportVectorSolver\r
+{\r
+ private double[] _cx;\r
+ private double[] _cy; \r
+ private final NyARPerspectiveProjectionMatrix _projection_mat;\r
+ private int _nmber_of_vertex;\r
+ public NyARTransportVectorSolver(final NyARPerspectiveProjectionMatrix i_projection_mat_ref,int i_max_vertex)\r
+ {\r
+ this._projection_mat=i_projection_mat_ref;\r
+ this._cx=new double[i_max_vertex];\r
+ this._cy=new double[i_max_vertex]; \r
+ return;\r
+ }\r
+ private double _a00,_a01_10,_a02_20,_a11,_a12_21,_a22;\r
+ /**\r
+ * 画面上の座標群を指定します。\r
+ * @param i_ref_vertex_2d\r
+ * 歪み矯正済の画面上の頂点座標群への参照値を指定します。\r
+ * @throws NyARException\r
+ * \r
+ */\r
+ public void set2dVertex(NyARDoublePoint2d[] i_ref_vertex_2d,int i_number_of_vertex) throws NyARException\r
+ {\r
+ //3x2nと2n*3の行列から、最小二乗法計算するために3x3マトリクスを作る。 \r
+ //行列[A]の3列目のキャッシュ\r
+ final double[] cx=this._cx;\r
+ final double[] cy=this._cy;\r
+ \r
+ double m22;\r
+ double p00=this._projection_mat.m00;\r
+ double p01=this._projection_mat.m01;\r
+ double p11=this._projection_mat.m11;\r
+ double p12=this._projection_mat.m12;\r
+ double p02=this._projection_mat.m02;\r
+ double w1,w2,w3,w4;\r
+ \r
+ this._a00=i_number_of_vertex*p00*p00;\r
+ this._a01_10=i_number_of_vertex*p00*p01;\r
+ this._a11=i_number_of_vertex*(p01*p01+p11*p11);\r
+ \r
+ //[A]T*[A]の計算\r
+ m22=0;\r
+ w1=w2=0;\r
+ for(int i=0;i<i_number_of_vertex;i++){\r
+ //座標を保存しておく。\r
+ w3=p02-(cx[i]=i_ref_vertex_2d[i].x);\r
+ w4=p12-(cy[i]=i_ref_vertex_2d[i].y);\r
+ w1+=w3;\r
+ w2+=w4;\r
+ m22+=w3*w3+w4*w4;\r
+ }\r
+ this._a02_20=w1*p00;\r
+ this._a12_21=p01*w1+p11*w2;\r
+ this._a22=m22;\r
+\r
+ this._nmber_of_vertex=i_number_of_vertex;\r
+ return;\r
+ }\r
+ \r
+ /**\r
+ * 画面座標群と3次元座標群から、平行移動量を計算します。\r
+ * 2d座標系は、直前に実行したset2dVertexのものを使用します。\r
+ * @param i_vertex_2d\r
+ * 直前のset2dVertexコールで指定したものと同じものを指定してください。\r
+ * @param i_vertex3d\r
+ * 3次元空間の座標群を設定します。頂点の順番は、画面座標群と同じ順序で格納してください。\r
+ * @param o_transfer\r
+ * @throws NyARException\r
+ */\r
+ public void solveTransportVector(NyARDoublePoint3d[] i_vertex3d,NyARDoublePoint3d o_transfer) throws NyARException\r
+ {\r
+ final int number_of_vertex=this._nmber_of_vertex;\r
+ final double p00=this._projection_mat.m00;\r
+ final double p01=this._projection_mat.m01;\r
+ final double p02=this._projection_mat.m02;\r
+ final double p11=this._projection_mat.m11;\r
+ final double p12=this._projection_mat.m12;\r
+ //行列[A]の3列目のキャッシュ\r
+ final double[] cx=this._cx;\r
+ final double[] cy=this._cy; \r
+ \r
+ //回転行列を元座標の頂点群に適応\r
+ //[A]T*[b]を計算\r
+ double b1=0,b2=0,b3=0;\r
+ for(int i=0;i<number_of_vertex;i++)\r
+ {\r
+ double w1=i_vertex3d[i].z*cx[i]-p00*i_vertex3d[i].x-p01*i_vertex3d[i].y-p02*i_vertex3d[i].z;\r
+ double w2=i_vertex3d[i].z*cy[i]-p11*i_vertex3d[i].y-p12*i_vertex3d[i].z;\r
+ b1+=w1;\r
+ b2+=w2;\r
+ b3+=cx[i]*w1+cy[i]*w2;\r
+ }\r
+ //[A]T*[b]を計算\r
+ b3=p02*b1+p12*b2-b3;//順番変えたらダメよ\r
+ b2=p01*b1+p11*b2;\r
+ b1=p00*b1;\r
+ //([A]T*[A])*[T]=[A]T*[b]を方程式で解く。\r
+ //a01とa10を0と仮定しても良いんじゃないかな?\r
+ double a00=this._a00;\r
+ double a01=this._a01_10;\r
+ double a02=this._a02_20;\r
+ double a11=this._a11;\r
+ double a12=this._a12_21;\r
+ double a22=this._a22;\r
+ \r
+ double t1=a22*b2-a12*b3;\r
+ double t2=a12*b2-a11*b3;\r
+ double t3=a01*b3-a02*b2;\r
+ double t4=a12*a12-a11*a22;\r
+ double t5=a02*a12-a01*a22;\r
+ double t6=a02*a11-a01*a12;\r
+ double det=a00*t4-a01*t5 + a02*t6;\r
+ o_transfer.x= (a01*t1 - a02*t2 +b1*t4)/det;\r
+ o_transfer.y=-(a00*t1 + a02*t3 +b1*t5)/det;\r
+ o_transfer.z= (a00*t2 + a01*t3 +b1*t6)/det;\r
+ \r
+ \r
+ return;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.transmat.solver;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.NyARMat;\r
+import jp.nyatla.nyartoolkit.core.param.NyARPerspectiveProjectionMatrix;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+\r
+/**\r
+ * 並進ベクトル[T]を3次元座標[b]と基点の回転済行列[M]から計算します。\r
+ * ARToolKit互換の数値を計算します。\r
+ *\r
+ */\r
+public class NyARTransportVectorSolver_ARToolKit implements INyARTransportVectorSolver\r
+{\r
+ private final NyARMat _mat_at = new NyARMat(3,8);//3,NUMBER_OF_VERTEX*2\r
+ private final NyARMat _mat_a = new NyARMat(8,3);//NUMBER_OF_VERTEX,3\r
+ private final NyARMat _mat_t = new NyARMat(3,3);//NUMBER_OF_VERTEX,3\r
+ private final NyARMat _mat_c = new NyARMat(8,1);//NUMBER_OF_VERTEX * 2, 1\r
+ private final NyARMat _mat_e = new NyARMat(3,1);\r
+ private final NyARMat _mat_f = new NyARMat(3,1);\r
+ private double[] _cx=new double[4];\r
+ private double[] _cy=new double[4];\r
+ \r
+ private final NyARPerspectiveProjectionMatrix _projection_mat;\r
+ public NyARTransportVectorSolver_ARToolKit(final NyARPerspectiveProjectionMatrix i_projection_mat_ref)\r
+ {\r
+ this._projection_mat=i_projection_mat_ref;\r
+ //aとb(aの転置行列)の固定部分を設定。\r
+ final double[][] mata = this._mat_a.getArray();\r
+ final double[][] matat = this._mat_at.getArray();\r
+\r
+ //変換用行列のcpara部分を先に作成\r
+ for (int i = 0; i < 4; i++) {\r
+ final int x2 = i * 2;\r
+ mata[x2][0] = matat[0][x2] = i_projection_mat_ref.m00;// mat_a->m[j*6+0]=mat_b->m[num*0+j*2] =cpara[0][0];\r
+ mata[x2][1] = matat[1][x2] = i_projection_mat_ref.m01;// mat_a->m[j*6+1]=mat_b->m[num*2+j*2]=cpara[0][1];\r
+ mata[x2 + 1][0] = matat[0][x2 + 1] = 0.0;// mat_a->m[j*6+3] =mat_b->m[num*0+j*2+1]= 0.0;\r
+ mata[x2 + 1][1] = matat[1][x2 + 1] = i_projection_mat_ref.m11;// mat_a->m[j*6+4] =mat_b->m[num*2+j*2+1]= cpara[1][1];\r
+ }\r
+ return;\r
+ }\r
+ public void set2dVertex(NyARDoublePoint2d[] i_ref_vertex_2d,int i_number_of_vertex) throws NyARException\r
+ { \r
+ assert(i_number_of_vertex==4);\r
+ final double[] cx=this._cx;\r
+ final double[] cy=this._cy;\r
+ final double cpara02=this._projection_mat.m02;\r
+ final double cpara12=this._projection_mat.m12; \r
+ final NyARMat mat_t=this._mat_t;\r
+ final double[][] mata = this._mat_a.getArray();\r
+ final double[][] matat= this._mat_at.getArray();\r
+ for (int i = 0; i < 4; i++){\r
+ cx[i]=i_ref_vertex_2d[i].x;\r
+ cy[i]=i_ref_vertex_2d[i].y;\r
+ final int x2 = i * 2; \r
+ mata[x2][2] = matat[2][x2] = cpara02 - i_ref_vertex_2d[i].x;// mat_a->m[j*6+2]=mat_b->m[num*4+j*2]=cpara[0][2]-pos2d[j][0];\r
+ mata[x2 + 1][2] = matat[2][x2 + 1] = cpara12 - i_ref_vertex_2d[i].y;// mat_a->m[j*6+5]=mat_b->m[num*4+j*2+1]=cpara[1][2]-pos2d[j][1];\r
+ }\r
+ //T(3x3行列)の作成\r
+ mat_t.matrixMul(this._mat_at, this._mat_a);\r
+ mat_t.matrixSelfInv(); \r
+ return; \r
+ }\r
+ /**\r
+ * 画面座標群と3次元座標群から、平行移動量を計算します。\r
+ * 2d座標系は、直前に実行したset2dVertexのものを使用します。\r
+ * @param i_vertex_2d\r
+ * 直前のset2dVertexコールで指定したものと同じものを指定してください。\r
+ * @param i_vertex3d\r
+ * 3次元空間の座標群を設定します。頂点の順番は、画面座標群と同じ順序で格納してください。\r
+ * @param o_transfer\r
+ * @throws NyARException\r
+ */\r
+ public void solveTransportVector(NyARDoublePoint3d[] i_vertex3d,NyARDoublePoint3d o_transfer) throws NyARException\r
+ {\r
+ final double[][] matc = this._mat_c.getArray();\r
+ final double cpara00=this._projection_mat.m00;\r
+ final double cpara01=this._projection_mat.m01;\r
+ final double cpara02=this._projection_mat.m02;\r
+ final double cpara11=this._projection_mat.m11;\r
+ final double cpara12=this._projection_mat.m12;\r
+ final double[] cx=this._cx;\r
+ final double[] cy=this._cy;\r
+ \r
+ //(3D座標?)を一括請求\r
+ for (int i = 0; i < 4; i++) {\r
+ final int x2 = i+i;\r
+ final NyARDoublePoint3d point3d_ptr=i_vertex3d[i];\r
+ //透視変換?\r
+ matc[x2][0] = point3d_ptr.z * cx[i] - cpara00 * point3d_ptr.x - cpara01 * point3d_ptr.y - cpara02 * point3d_ptr.z;// mat_c->m[j*2+0] = wz*pos2d[j][0]-cpara[0][0]*wx-cpara[0][1]*wy-cpara[0][2]*wz;\r
+ matc[x2 + 1][0] = point3d_ptr.z * cy[i] - cpara11 * point3d_ptr.y - cpara12 * point3d_ptr.z;// mat_c->m[j*2+1]= wz*pos2d[j][1]-cpara[1][1]*wy-cpara[1][2]*wz;\r
+ }\r
+ this._mat_e.matrixMul(this._mat_at,this._mat_c);\r
+ this._mat_f.matrixMul(this._mat_t, this._mat_e);\r
+ \r
+ final double[][] matf = this._mat_f.getArray();\r
+ o_transfer.x= matf[0][0];// trans[0] = mat_f->m[0];\r
+ o_transfer.y= matf[1][0];\r
+ o_transfer.z= matf[2][0];// trans[2] = mat_f->m[2];\r
+ return; \r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+\r
+public class NyARDoublePoint2d\r
+{\r
+ public double x;\r
+ public double y;\r
+ /**\r
+ * 配列ファクトリ\r
+ * @param i_number\r
+ * @return\r
+ */\r
+ public static NyARDoublePoint2d[] createArray(int i_number)\r
+ {\r
+ NyARDoublePoint2d[] ret=new NyARDoublePoint2d[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARDoublePoint2d();\r
+ }\r
+ return ret;\r
+ }\r
+ public static NyARDoublePoint2d[][] create2dArray(int i_length_x,int i_length_y)\r
+ {\r
+ NyARDoublePoint2d[][] ret=new NyARDoublePoint2d[i_length_y][i_length_x];\r
+ for(int i=0;i<i_length_y;i++)\r
+ {\r
+ for(int i2=0;i2<i_length_x;i2++)\r
+ {\r
+ ret[i][i2]=new NyARDoublePoint2d();\r
+ }\r
+ }\r
+ return ret;\r
+ }\r
+ public NyARDoublePoint2d()\r
+ {\r
+ this.x=0;\r
+ this.y=0;\r
+ return;\r
+ } \r
+ public NyARDoublePoint2d(double i_x,double i_y)\r
+ {\r
+ this.x=i_x;\r
+ this.y=i_y;\r
+ return;\r
+ }\r
+ public NyARDoublePoint2d(NyARDoublePoint2d i_src)\r
+ {\r
+ this.x=i_src.x;\r
+ this.y=i_src.y;\r
+ return;\r
+ }\r
+ public NyARDoublePoint2d(NyARIntPoint2d i_src)\r
+ {\r
+ this.x=(double)i_src.x;\r
+ this.y=(double)i_src.y;\r
+ return;\r
+ }\r
+ public void setValue(NyARDoublePoint2d i_src)\r
+ {\r
+ this.x=i_src.x;\r
+ this.y=i_src.y;\r
+ return;\r
+ }\r
+ public void setValue(NyARIntPoint2d i_src)\r
+ {\r
+ this.x=(double)i_src.x;\r
+ this.y=(double)i_src.y;\r
+ return;\r
+ }\r
+ /**\r
+ * 格納値をベクトルとして、距離を返します。\r
+ * @return\r
+ */\r
+ public double dist()\r
+ {\r
+ return Math.sqrt(this.x*this.x+this.y+this.y);\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+public class NyARDoublePoint3d\r
+{\r
+ public double x;\r
+ public double y;\r
+ public double z;\r
+ /**\r
+ * 配列ファクトリ\r
+ * @param i_number\r
+ * @return\r
+ */\r
+ public static NyARDoublePoint3d[] createArray(int i_number)\r
+ {\r
+ NyARDoublePoint3d[] ret=new NyARDoublePoint3d[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARDoublePoint3d();\r
+ }\r
+ return ret;\r
+ }\r
+ public void setValue(final NyARDoublePoint3d i_in)\r
+ {\r
+ this.x=i_in.x;\r
+ this.y=i_in.y;\r
+ this.z=i_in.z;\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+/**\r
+ * ヒストグラムを格納するクラスです。\r
+ */\r
+public class NyARHistgram\r
+{\r
+ /**\r
+ * サンプリング値の格納変数\r
+ */\r
+ public final int[] data;\r
+ /**\r
+ * 有効なサンプリング値の範囲。[0-data.length-1]\r
+ */\r
+ public int length;\r
+ /**\r
+ * 有効なサンプルの総数 data[i]\r
+ */\r
+ public int total_of_data;\r
+ \r
+ \r
+ \r
+ public NyARHistgram(int i_length)\r
+ {\r
+ this.data=new int[i_length];\r
+ this.length=i_length;\r
+ this.total_of_data=0;\r
+ }\r
+ /**\r
+ * 区間i_stからi_edまでの総データ数を返します。\r
+ * @param i_st\r
+ * @param i_ed\r
+ * @return\r
+ */\r
+ public int getTotal(int i_st,int i_ed)\r
+ {\r
+ assert(i_st<i_ed && i_ed<this.length);\r
+ int result=0;\r
+ int[] s=this.data;\r
+ for(int i=i_st;i<=i_ed;i++){\r
+ result+=s[i];\r
+ }\r
+ return result;\r
+ }\r
+ /**\r
+ * 指定したi_pos未満サンプルを0にします。\r
+ * @param i_pos\r
+ */\r
+ public void lowCut(int i_pos)\r
+ {\r
+ int s=0;\r
+ for(int i=0;i<i_pos;i++){\r
+ s+=this.data[i];\r
+ this.data[i]=0;\r
+ }\r
+ this.total_of_data-=s;\r
+ }\r
+ /**\r
+ * 指定したi_pos以上のサンプルを0にします。\r
+ * @param i_pos\r
+ */\r
+ public void highCut(int i_pos)\r
+ {\r
+ int s=0;\r
+ for(int i=this.length-1;i>=i_pos;i--){\r
+ s+=this.data[i];\r
+ this.data[i]=0;\r
+ }\r
+ this.total_of_data-=s;\r
+ }\r
+ /**\r
+ * 最小の値が格納されているサンプル番号を返します。\r
+ */\r
+ public int getMinSample()\r
+ {\r
+ int[] data=this.data;\r
+ int ret=this.length-1;\r
+ int min=data[ret];\r
+ for(int i=this.length-2;i>=0;i--)\r
+ {\r
+ if(data[i]<min){\r
+ min=data[i];\r
+ ret=i;\r
+ }\r
+ }\r
+ return ret;\r
+ }\r
+ /**\r
+ * サンプルの中で最小の値を返します。\r
+ * @return\r
+ */\r
+ public int getMinData()\r
+ {\r
+ return this.data[this.getMinSample()];\r
+ }\r
+ /**\r
+ * 平均値を計算します。\r
+ * @return\r
+ */\r
+ public int getAverage()\r
+ {\r
+ long sum=0;\r
+ for(int i=this.length-1;i>=0;i--)\r
+ {\r
+ sum+=this.data[i]*i;\r
+ }\r
+ return (int)(sum/this.total_of_data);\r
+ }\r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+/**\r
+ * @deprecated このクラスは名称変更のため、削除されます。\r
+ * @see NyARIntPoint2d\r
+ */\r
+public class NyARIntPoint extends NyARIntPoint2d\r
+{\r
+ /**\r
+ * 配列ファクトリ\r
+ * @param i_number\r
+ * @return\r
+ */\r
+ public static NyARIntPoint[] createArray(int i_number)\r
+ {\r
+ NyARIntPoint[] ret=new NyARIntPoint[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARIntPoint();\r
+ }\r
+ return ret;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+public class NyARIntPoint2d\r
+{\r
+ public int x;\r
+\r
+ public int y;\r
+ /**\r
+ * 配列ファクトリ\r
+ * @param i_number\r
+ * @return\r
+ */\r
+ public static NyARIntPoint2d[] createArray(int i_number)\r
+ {\r
+ NyARIntPoint2d[] ret=new NyARIntPoint2d[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARIntPoint2d();\r
+ }\r
+ return ret;\r
+ }\r
+ public static void copyArray(final NyARIntPoint2d[] i_from,NyARIntPoint2d[] i_to)\r
+ {\r
+ for(int i=i_from.length-1;i>=0;i--)\r
+ {\r
+ i_to[i].x=i_from[i].x;\r
+ i_to[i].y=i_from[i].y;\r
+ }\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+public class NyARIntRect\r
+{\r
+ public int x;\r
+\r
+ public int y;\r
+\r
+ public int w;\r
+\r
+ public int h;\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+public class NyARIntSize\r
+{\r
+ public int h;\r
+ public int w;\r
+ public NyARIntSize()\r
+ {\r
+ this.w=0;\r
+ this.h=0;\r
+ return; \r
+ }\r
+ public NyARIntSize(NyARIntSize i_ref_object)\r
+ {\r
+ this.w=i_ref_object.w;\r
+ this.h=i_ref_object.h;\r
+ return; \r
+ }\r
+ public NyARIntSize(int i_width,int i_height)\r
+ {\r
+ this.w=i_width;\r
+ this.h=i_height;\r
+ return;\r
+ }\r
+ /**\r
+ * サイズが同一であるかを確認する。\r
+ * \r
+ * @param i_width\r
+ * @param i_height\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public boolean isEqualSize(int i_width, int i_height)\r
+ {\r
+ if (i_width == this.w && i_height == this.h) {\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * サイズが同一であるかを確認する。\r
+ * \r
+ * @param i_width\r
+ * @param i_height\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public boolean isEqualSize(NyARIntSize i_size)\r
+ {\r
+ if (i_size.w == this.w && i_size.h == this.h) {\r
+ return true;\r
+ }\r
+ return false;\r
+\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types;\r
+\r
+/**\r
+ * 0=dx*x+dy*y+cのパラメータを格納します。\r
+ * x,yの増加方向は、x=L→R,y=B→Tです。 \r
+ *\r
+ */\r
+public class NyARLinear\r
+{\r
+ public double dx;//dx軸の増加量\r
+ public double dy;//dy軸の増加量\r
+ public double c;//切片\r
+ public static NyARLinear[] createArray(int i_number)\r
+ {\r
+ NyARLinear[] ret=new NyARLinear[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARLinear();\r
+ }\r
+ return ret;\r
+ } \r
+ public final void copyFrom(NyARLinear i_source)\r
+ {\r
+ this.dx=i_source.dx;\r
+ this.dy=i_source.dy;\r
+ this.c=i_source.c;\r
+ return;\r
+ }\r
+ /**\r
+ * 2直線の交点を計算します。\r
+ * @param l_line_i\r
+ * @param l_line_2\r
+ * @param o_point\r
+ * @return\r
+ */\r
+ public final static boolean crossPos(NyARLinear l_line_i,NyARLinear l_line_2,NyARDoublePoint2d o_point)\r
+ {\r
+ final double w1 = l_line_2.dy * l_line_i.dx - l_line_i.dy * l_line_2.dx;\r
+ if (w1 == 0.0) {\r
+ return false;\r
+ }\r
+ o_point.x = (l_line_2.dx * l_line_i.c - l_line_i.dx * l_line_2.c) / w1;\r
+ o_point.y = (l_line_i.dy * l_line_2.c - l_line_2.dy * l_line_i.c) / w1;\r
+ return true;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+public interface INyARDoubleMatrix\r
+{\r
+ /**\r
+ * 配列の内容を行列に設定する。\r
+ * 遅いので余り使わないでね。\r
+ * @param o_value\r
+ */\r
+ public void setValue(double[] i_value);\r
+ /**\r
+ * 行列の内容を配列に返す。\r
+ * 遅いので余り使わないでね。\r
+ * @param o_value\r
+ */\r
+ public void getValue(double[] o_value);\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+public class NyARDoubleMatrix22 implements INyARDoubleMatrix\r
+{\r
+ public double m00;\r
+ public double m01;\r
+ public double m10;\r
+ public double m11;\r
+ /**\r
+ * 遅いからあんまり使わないでね。\r
+ */\r
+ public void setValue(double[] i_value)\r
+ {\r
+ this.m00=i_value[0];\r
+ this.m01=i_value[1];\r
+ this.m10=i_value[3];\r
+ this.m11=i_value[4];\r
+ return;\r
+ }\r
+ /**\r
+ * 遅いからあんまり使わないでね。\r
+ */\r
+ public void getValue(double[] o_value)\r
+ {\r
+ o_value[0]=this.m00;\r
+ o_value[1]=this.m01;\r
+ o_value[3]=this.m10;\r
+ o_value[4]=this.m11;\r
+ return;\r
+ }\r
+ public boolean inverse(NyARDoubleMatrix22 i_src)\r
+ {\r
+ final double a11,a12,a21,a22;\r
+ a11=i_src.m00;\r
+ a12=i_src.m01;\r
+ a21=i_src.m10;\r
+ a22=i_src.m11;\r
+ double det=a11*a22-a12*a21;\r
+ if(det==0){\r
+ return false;\r
+ }\r
+ det=1/det;\r
+ this.m00=a22*det;\r
+ this.m01=-a12*det;\r
+ this.m10=a21*det;\r
+ this.m11=-a11*det;\r
+ return true;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint3d;\r
+\r
+public class NyARDoubleMatrix33 implements INyARDoubleMatrix\r
+{\r
+ public double m00;\r
+ public double m01;\r
+ public double m02;\r
+ public double m10;\r
+ public double m11;\r
+ public double m12;\r
+ public double m20;\r
+ public double m21;\r
+ public double m22;\r
+ public static NyARDoubleMatrix33[] createArray(int i_number)\r
+ {\r
+ NyARDoubleMatrix33[] ret=new NyARDoubleMatrix33[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARDoubleMatrix33();\r
+ }\r
+ return ret;\r
+ }\r
+ /**\r
+ * 遅いからあんまり使わないでね。\r
+ */\r
+ public void setValue(double[] i_value)\r
+ {\r
+ this.m00=i_value[0];\r
+ this.m01=i_value[1];\r
+ this.m02=i_value[2];\r
+ this.m10=i_value[3];\r
+ this.m11=i_value[4];\r
+ this.m12=i_value[5];\r
+ this.m20=i_value[6];\r
+ this.m21=i_value[7];\r
+ this.m22=i_value[8];\r
+ return;\r
+ }\r
+ public void setValue(NyARDoubleMatrix33 i_value)\r
+ {\r
+ this.m00=i_value.m00;\r
+ this.m01=i_value.m01;\r
+ this.m02=i_value.m02;\r
+ this.m10=i_value.m10;\r
+ this.m11=i_value.m11;\r
+ this.m12=i_value.m12;\r
+ this.m20=i_value.m20;\r
+ this.m21=i_value.m21;\r
+ this.m22=i_value.m22;\r
+ return;\r
+ } \r
+ /**\r
+ * 遅いからあんまり使わないでね。\r
+ */\r
+ public void getValue(double[] o_value)\r
+ {\r
+ o_value[0]=this.m00;\r
+ o_value[1]=this.m01;\r
+ o_value[2]=this.m02;\r
+ o_value[3]=this.m10;\r
+ o_value[4]=this.m11;\r
+ o_value[5]=this.m12;\r
+ o_value[6]=this.m20;\r
+ o_value[7]=this.m21;\r
+ o_value[8]=this.m22;\r
+ return;\r
+ }\r
+ public boolean inverse(NyARDoubleMatrix33 i_src)\r
+ {\r
+ final double a11,a12,a13,a21,a22,a23,a31,a32,a33;\r
+ final double b11,b12,b13,b21,b22,b23,b31,b32,b33; \r
+ a11=i_src.m00;a12=i_src.m01;a13=i_src.m02;\r
+ a21=i_src.m10;a22=i_src.m11;a23=i_src.m12;\r
+ a31=i_src.m20;a32=i_src.m21;a33=i_src.m22;\r
+ \r
+ b11=a22*a33-a23*a32;\r
+ b12=a32*a13-a33*a12;\r
+ b13=a12*a23-a13*a22;\r
+ \r
+ b21=a23*a31-a21*a33;\r
+ b22=a33*a11-a31*a13;\r
+ b23=a13*a21-a11*a23;\r
+ \r
+ b31=a21*a32-a22*a31;\r
+ b32=a31*a12-a32*a11;\r
+ b33=a11*a22-a12*a21;\r
+ \r
+ double det_1=a11*b11+a21*b12+a31*b13;\r
+ if(det_1==0){\r
+ return false;\r
+ }\r
+ det_1=1/det_1;\r
+\r
+ this.m00=b11*det_1;\r
+ this.m01=b12*det_1;\r
+ this.m02=b13*det_1;\r
+ \r
+ this.m10=b21*det_1;\r
+ this.m11=b22*det_1;\r
+ this.m12=b23*det_1;\r
+ \r
+ this.m20=b31*det_1;\r
+ this.m21=b32*det_1;\r
+ this.m22=b33*det_1;\r
+ \r
+ return true;\r
+ }\r
+ /**\r
+ * この関数は、0-PIの間で値を返します。\r
+ * @param o_out\r
+ */\r
+ public final void getZXYAngle(NyARDoublePoint3d o_out)\r
+ {\r
+ double sina = this.m21;\r
+ if (sina >= 1.0) {\r
+ o_out.x = Math.PI / 2;\r
+ o_out.y = 0;\r
+ o_out.z = Math.atan2(-this.m10, this.m00);\r
+ } else if (sina <= -1.0) {\r
+ o_out.x = -Math.PI / 2;\r
+ o_out.y = 0;\r
+ o_out.z = Math.atan2(-this.m10, this.m00);\r
+ } else {\r
+ o_out.x = Math.asin(sina);\r
+ o_out.z = Math.atan2(-this.m01, this.m11);\r
+ o_out.y = Math.atan2(-this.m20, this.m22);\r
+ }\r
+ }\r
+ public final void setZXYAngle(final double i_x, final double i_y, final double i_z)\r
+ {\r
+ final double sina = Math.sin(i_x);\r
+ final double cosa = Math.cos(i_x);\r
+ final double sinb = Math.sin(i_y);\r
+ final double cosb = Math.cos(i_y);\r
+ final double sinc = Math.sin(i_z);\r
+ final double cosc = Math.cos(i_z);\r
+ this.m00 = cosc * cosb - sinc * sina * sinb;\r
+ this.m01 = -sinc * cosa;\r
+ this.m02 = cosc * sinb + sinc * sina * cosb;\r
+ this.m10 = sinc * cosb + cosc * sina * sinb;\r
+ this.m11 = cosc * cosa;\r
+ this.m12 = sinc * sinb - cosc * sina * cosb;\r
+ this.m20 = -cosa * sinb;\r
+ this.m21 = sina;\r
+ this.m22 = cosb * cosa;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+public class NyARDoubleMatrix34 implements INyARDoubleMatrix\r
+{\r
+ public double m00;\r
+ public double m01;\r
+ public double m02;\r
+ public double m03;\r
+ public double m10;\r
+ public double m11;\r
+ public double m12;\r
+ public double m13;\r
+ public double m20;\r
+ public double m21;\r
+ public double m22;\r
+ public double m23;\r
+ public void setValue(double[] i_value)\r
+ {\r
+ this.m00=i_value[0];\r
+ this.m01=i_value[1];\r
+ this.m02=i_value[2];\r
+ this.m03=i_value[3];\r
+ this.m10=i_value[4];\r
+ this.m11=i_value[5];\r
+ this.m12=i_value[6];\r
+ this.m13=i_value[7];\r
+ this.m20=i_value[8];\r
+ this.m21=i_value[9];\r
+ this.m22=i_value[10];\r
+ this.m23=i_value[11];\r
+ return;\r
+ }\r
+ public void getValue(double[] o_value)\r
+ {\r
+ o_value[0]=this.m00;\r
+ o_value[1]=this.m01;\r
+ o_value[2]=this.m02;\r
+ o_value[3]=this.m03;\r
+ o_value[4]=this.m10;\r
+ o_value[5]=this.m11;\r
+ o_value[6]=this.m12;\r
+ o_value[7]=this.m13;\r
+ o_value[8]=this.m20;\r
+ o_value[9]=this.m21;\r
+ o_value[10]=this.m22;\r
+ o_value[11]=this.m23;\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.matrix;\r
+\r
+\r
+public class NyARDoubleMatrix44 implements INyARDoubleMatrix\r
+{\r
+ public double m00;\r
+ public double m01;\r
+ public double m02;\r
+ public double m03;\r
+ public double m10;\r
+ public double m11;\r
+ public double m12;\r
+ public double m13;\r
+ public double m20;\r
+ public double m21;\r
+ public double m22;\r
+ public double m23;\r
+ public double m30;\r
+ public double m31;\r
+ public double m32;\r
+ public double m33;\r
+ public static NyARDoubleMatrix44[] createArray(int i_number)\r
+ {\r
+ NyARDoubleMatrix44[] ret=new NyARDoubleMatrix44[i_number];\r
+ for(int i=0;i<i_number;i++)\r
+ {\r
+ ret[i]=new NyARDoubleMatrix44();\r
+ }\r
+ return ret;\r
+ }\r
+ /**\r
+ * 遅いからあんまり使わないでね。\r
+ */\r
+ public void setValue(double[] i_value)\r
+ {\r
+ this.m00=i_value[ 0];\r
+ this.m01=i_value[ 1];\r
+ this.m02=i_value[ 2];\r
+ this.m03=i_value[ 3];\r
+ this.m10=i_value[ 4];\r
+ this.m11=i_value[ 5];\r
+ this.m12=i_value[ 6];\r
+ this.m13=i_value[ 7];\r
+ this.m20=i_value[ 8];\r
+ this.m21=i_value[ 9];\r
+ this.m22=i_value[10];\r
+ this.m23=i_value[11];\r
+ this.m30=i_value[12];\r
+ this.m31=i_value[13];\r
+ this.m32=i_value[14];\r
+ this.m33=i_value[15];\r
+ return;\r
+ }\r
+ /**\r
+ * 遅いからあんまり使わないでね。\r
+ */\r
+ public void getValue(double[] o_value)\r
+ {\r
+ o_value[ 0]=this.m00;\r
+ o_value[ 1]=this.m01;\r
+ o_value[ 2]=this.m02;\r
+ o_value[ 3]=this.m03;\r
+ o_value[ 4]=this.m10;\r
+ o_value[ 5]=this.m11;\r
+ o_value[ 6]=this.m12;\r
+ o_value[ 7]=this.m13;\r
+ o_value[ 8]=this.m20;\r
+ o_value[ 9]=this.m21;\r
+ o_value[10]=this.m22;\r
+ o_value[11]=this.m23;\r
+ o_value[12]=this.m30;\r
+ o_value[13]=this.m31;\r
+ o_value[14]=this.m32;\r
+ o_value[15]=this.m33;\r
+ return;\r
+ }\r
+ public boolean inverse(NyARDoubleMatrix44 i_src)\r
+ {\r
+ final double a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34,a41,a42,a43,a44;\r
+ final double b11,b12,b13,b14,b21,b22,b23,b24,b31,b32,b33,b34,b41,b42,b43,b44; \r
+ double t1,t2,t3,t4,t5,t6;\r
+ a11=i_src.m00;a12=i_src.m01;a13=i_src.m02;a14=i_src.m03;\r
+ a21=i_src.m10;a22=i_src.m11;a23=i_src.m12;a24=i_src.m13;\r
+ a31=i_src.m20;a32=i_src.m21;a33=i_src.m22;a34=i_src.m23;\r
+ a41=i_src.m30;a42=i_src.m31;a43=i_src.m32;a44=i_src.m33;\r
+ \r
+ t1=a33*a44-a34*a43;\r
+ t2=a34*a42-a32*a44;\r
+ t3=a32*a43-a33*a42;\r
+ t4=a34*a41-a31*a44;\r
+ t5=a31*a43-a33*a41;\r
+ t6=a31*a42-a32*a41;\r
+ \r
+ b11=a22*t1+a23*t2+a24*t3;\r
+ b21=-(a23*t4+a24*t5+a21*t1);\r
+ b31=a24*t6-a21*t2+a22*t4;\r
+ b41=-(a21*t3-a22*t5+a23*t6);\r
+ \r
+ t1=a43*a14-a44*a13;\r
+ t2=a44*a12-a42*a14;\r
+ t3=a42*a13-a43*a12;\r
+ t4=a44*a11-a41*a14;\r
+ t5=a41*a13-a43*a11;\r
+ t6=a41*a12-a42*a11;\r
+\r
+ b12=-(a32*t1+a33*t2+a34*t3);\r
+ b22=a33*t4+a34*t5+a31*t1;\r
+ b32=-(a34*t6-a31*t2+a32*t4);\r
+ b42=a31*t3-a32*t5+a33*t6;\r
+ \r
+ t1=a13*a24-a14*a23;\r
+ t2=a14*a22-a12*a24;\r
+ t3=a12*a23-a13*a22;\r
+ t4=a14*a21-a11*a24;\r
+ t5=a11*a23-a13*a21;\r
+ t6=a11*a22-a12*a21;\r
+\r
+ b13=a42*t1+a43*t2+a44*t3;\r
+ b23=-(a43*t4+a44*t5+a41*t1);\r
+ b33=a44*t6-a41*t2+a42*t4;\r
+ b43=-(a41*t3-a42*t5+a43*t6);\r
+\r
+ t1=a23*a34-a24*a33;\r
+ t2=a24*a32-a22*a34;\r
+ t3=a22*a33-a23*a32;\r
+ t4=a24*a31-a21*a34; \r
+ t5=a21*a33-a23*a31;\r
+ t6=a21*a32-a22*a31;\r
+\r
+ b14=-(a12*t1+a13*t2+a14*t3);\r
+ b24=a13*t4+a14*t5+a11*t1;\r
+ b34=-(a14*t6-a11*t2+a12*t4);\r
+ b44=a11*t3-a12*t5+a13*t6;\r
+ \r
+ double det_1=(a11*b11+a21*b12+a31*b13+a41*b14);\r
+ if(det_1==0){\r
+ return false;\r
+ }\r
+ det_1=1/det_1;\r
+\r
+ this.m00=b11*det_1;\r
+ this.m01=b12*det_1;\r
+ this.m02=b13*det_1;\r
+ this.m03=b14*det_1;\r
+ \r
+ this.m10=b21*det_1;\r
+ this.m11=b22*det_1;\r
+ this.m12=b23*det_1;\r
+ this.m13=b24*det_1;\r
+ \r
+ this.m20=b31*det_1;\r
+ this.m21=b32*det_1;\r
+ this.m22=b33*det_1;\r
+ this.m23=b34*det_1;\r
+ \r
+ this.m30=b41*det_1;\r
+ this.m31=b42*det_1;\r
+ this.m32=b43*det_1;\r
+ this.m33=b44*det_1;\r
+ \r
+ return true;\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.stack;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+public class NyARIntPointStack extends NyObjectStack<NyARIntPoint2d>\r
+{\r
+ public NyARIntPointStack(int i_length)\r
+ {\r
+ super(i_length,NyARIntPoint2d.class);\r
+ return;\r
+ }\r
+ protected NyARIntPoint2d createElement()\r
+ {\r
+ return new NyARIntPoint2d();\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.stack;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntRect;\r
+\r
+public class NyARIntRectStack extends NyObjectStack<NyARIntRect>\r
+{\r
+ public NyARIntRectStack(int i_length)\r
+ {\r
+ super(i_length,NyARIntRect.class);\r
+ }\r
+ protected NyARIntRect createElement()\r
+ {\r
+ return new NyARIntRect();\r
+ }\r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.types.stack;\r
+import java.lang.reflect.*;\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+\r
+\r
+\r
+\r
+/**\r
+ * オンデマンド割り当てをするオブジェクト配列。\r
+ * 配列には実体を格納します。\r
+ */\r
+public abstract class NyObjectStack<T>\r
+{\r
+ private final static int ARRAY_APPEND_STEP = 64;\r
+\r
+ protected final T[] _items;\r
+\r
+ private int _allocated_size;\r
+\r
+ protected int _length;\r
+\r
+ /**\r
+ * 最大ARRAY_MAX個の動的割り当てバッファを準備する。\r
+ * \r
+ * @param i_array\r
+ * @param i_element_type\r
+ * JavaのGenedicsの制限突破\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ protected NyObjectStack(int i_length,Class<T> i_element_type)\r
+ {\r
+ // ポインタだけははじめに確保しておく\r
+ this._items = (T[])Array.newInstance(i_element_type, i_length);\r
+ // アロケート済サイズと、使用中個数をリセット\r
+ this._allocated_size = 0;\r
+ this._length = 0;\r
+ return;\r
+ }\r
+ protected abstract T createElement();\r
+ /**\r
+ * ポインタを1進めて、その要素を予約し、その要素へのポインタを返します。\r
+ * 特定型に依存させるときには、継承したクラスでこの関数をオーバーライドしてください。\r
+ */\r
+ public final T prePush() throws NyARException\r
+ {\r
+ // 必要に応じてアロケート\r
+ if (this._length >= this._allocated_size) {\r
+ // 要求されたインデクスは範囲外\r
+ if (this._length >= this._items.length) {\r
+ throw new NyARException();\r
+ }\r
+ // 追加アロケート範囲を計算\r
+ int range = this._length + ARRAY_APPEND_STEP;\r
+ if (range >= this._items.length) {\r
+ range = this._items.length;\r
+ }\r
+ // アロケート\r
+ this.onReservRequest(this._allocated_size, range, this._items);\r
+ this._allocated_size = range;\r
+ }\r
+ // 使用領域を+1して、予約した領域を返す。\r
+ T ret = this._items[this._length];\r
+ this._length++;\r
+ return ret;\r
+ }\r
+ /** \r
+ * 見かけ上の要素数を1減らして、最後尾のアイテムを返します。\r
+ * @return\r
+ */\r
+ public final T pop()\r
+ {\r
+ assert(this._length>=1);\r
+ this._length--;\r
+ return this._items[this._length];\r
+ }\r
+ /**\r
+ * 見かけ上の要素数をi_count個減らします。\r
+ * @param i_count\r
+ * @return\r
+ * NULLを返します。\r
+ */\r
+ public final void pops(int i_count)\r
+ {\r
+ assert(this._length>=i_count);\r
+ this._length-=i_count;\r
+ return;\r
+ } \r
+ \r
+ /**\r
+ * 0~i_number_of_item-1までの領域を予約します。\r
+ * 予約済の領域よりも小さい場合には、現在の長さを調整します。\r
+ * @param i_number_of_reserv\r
+ */\r
+ final public void reserv(int i_number_of_item) throws NyARException\r
+ {\r
+ // 必要に応じてアロケート\r
+ if (i_number_of_item >= this._allocated_size) {\r
+ // 要求されたインデクスは範囲外\r
+ if (i_number_of_item >= this._items.length) {\r
+ throw new NyARException();\r
+ }\r
+ // 追加アロケート範囲を計算\r
+ int range = i_number_of_item+ARRAY_APPEND_STEP;\r
+ if (range >= this._items.length) {\r
+ range = this._items.length;\r
+ }\r
+ // アロケート\r
+ this.onReservRequest(this._allocated_size, range, this._items);\r
+ this._allocated_size = range;\r
+ }\r
+ //見かけ上の配列サイズを指定\r
+ this._length=i_number_of_item;\r
+ return;\r
+ }\r
+ /**\r
+ * 必要に応じて、この関数を継承先クラスで実装して下さい。\r
+ * i_bufferの配列の、i_start番目からi_end-1番目までの要素に、オブジェクトを割り当てて下さい。\r
+ * @param i_start\r
+ * @param i_end\r
+ * @param i_buffer\r
+ */ \r
+ final protected void onReservRequest(int i_start, int i_end, Object[] i_buffer)\r
+ {\r
+ try { \r
+ for (int i = i_start; i < i_end; i++){\r
+ i_buffer[i] =createElement();\r
+ }\r
+ } catch(Exception e) { \r
+ e.printStackTrace(); \r
+ }\r
+ return;\r
+ }\r
+\r
+\r
+ /**\r
+ * 配列を返します。\r
+ * \r
+ * @return\r
+ */\r
+ public final T[] getArray()\r
+ {\r
+ return this._items;\r
+ }\r
+ public final T getItem(int i_index)\r
+ {\r
+ return this._items[i_index];\r
+ }\r
+ /**\r
+ * 配列の見かけ上の要素数を返却します。\r
+ * @return\r
+ */\r
+ public final int getLength()\r
+ {\r
+ return this._length;\r
+ }\r
+ /**\r
+ * 見かけ上の要素数をリセットします。\r
+ */\r
+ public final void clear()\r
+ {\r
+ this._length = 0;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+import jp.nyatla.nyartoolkit.*;\r
+/**\r
+ * 方程式を解く関数を定義します。\r
+ *\r
+ */\r
+public class NyAREquationSolver\r
+{\r
+ public static int solve2Equation(double i_a, double i_b, double i_c,double[] o_result)\r
+ {\r
+ assert i_a!=0;\r
+ return solve2Equation(i_b/i_a,i_c/i_a,o_result,0);\r
+ }\r
+ \r
+ public static int solve2Equation(double i_b, double i_c,double[] o_result)\r
+ {\r
+ return solve2Equation(i_b,i_c,o_result,0);\r
+ }\r
+ \r
+ public static int solve2Equation(double i_b, double i_c,double[] o_result,int i_result_st)\r
+ {\r
+ double t=i_b*i_b-4*i_c;\r
+ if(t<0){\r
+ //虚数根\r
+ return 0;\r
+ }\r
+ if(t==0){\r
+ //重根\r
+ o_result[i_result_st+0]=-i_b/(2);\r
+ return 1;\r
+ }\r
+ //実根2個\r
+ t=Math.sqrt(t);\r
+ o_result[i_result_st+0]=(-i_b+t)/(2);\r
+ o_result[i_result_st+1]=(-i_b-t)/(2);\r
+ return 2;\r
+ }\r
+\r
+ /**\r
+ * 3次方程式 a*x^3+b*x^2+c*x+d=0の実根を求める。 \r
+ * http://aoki2.si.gunma-u.ac.jp/JavaScript/src/3jisiki.html\r
+ * のコードを基にしてます。\r
+ * @param i_a\r
+ * X^3の係数\r
+ * @param i_b\r
+ * X^2の係数\r
+ * @param i_c\r
+ * X^1の係数\r
+ * @param i_d\r
+ * X^0の係数\r
+ * @param o_result\r
+ * 実根。double[3]を指定すること。\r
+ * @return\r
+ */\r
+ public static int solve3Equation(double i_a, double i_b, double i_c, double i_d,double[] o_result)\r
+ {\r
+ assert (i_a != 0);\r
+ return solve3Equation(i_b/i_a,i_c/i_a,i_d/i_a,o_result);\r
+ }\r
+ \r
+ /**\r
+ * 3次方程式 x^3+b*x^2+c*x+d=0の実根を求める。\r
+ * だけを求める。\r
+ * http://aoki2.si.gunma-u.ac.jp/JavaScript/src/3jisiki.html\r
+ * のコードを基にしてます。\r
+ * @param i_b\r
+ * X^2の係数\r
+ * @param i_c\r
+ * X^1の係数\r
+ * @param i_d\r
+ * X^0の係数\r
+ * @param o_result\r
+ * 実根。double[1]以上を指定すること。\r
+ * @return\r
+ */\r
+ public static int solve3Equation(double i_b, double i_c, double i_d,double[] o_result)\r
+ {\r
+ double tmp,b, p, q;\r
+ b = i_b/(3);\r
+ p = b * b - i_c / 3;\r
+ q = (b * (i_c - 2 * b * b) - i_d) / 2;\r
+ if ((tmp = q * q - p * p * p) == 0) {\r
+ // 重根\r
+ q = Math.cbrt(q);\r
+ o_result[0] = 2 * q - b;\r
+ o_result[1] = -q - b;\r
+ return 2;\r
+ } else if (tmp > 0) {\r
+ // 実根1,虚根2\r
+ double a3 = Math.cbrt(q + ((q > 0) ? 1 : -1) * Math.sqrt(tmp));\r
+ double b3 = p / a3;\r
+ o_result[0] = a3 + b3 - b;\r
+ // 虚根:-0.5*(a3+b3)-b,Math.abs(a3-b3)*Math.sqrt(3.0)/2\r
+ return 1;\r
+ } else {\r
+ // 実根3\r
+ tmp = 2 * Math.sqrt(p);\r
+ double t = Math.acos(q / (p * tmp / 2));\r
+ o_result[0] = tmp * Math.cos(t / 3) - b;\r
+ o_result[1] = tmp * Math.cos((t + 2 * Math.PI) / 3) - b;\r
+ o_result[2] = tmp * Math.cos((t + 4 * Math.PI) / 3) - b;\r
+ return 3;\r
+ }\r
+ }\r
+\r
+ \r
+ \r
+ /**\r
+ * 4次方程式の実根だけを求める。\r
+ * @param i_a\r
+ * X^3の係数\r
+ * @param i_b\r
+ * X^2の係数\r
+ * @param i_c\r
+ * X^1の係数\r
+ * @param i_d\r
+ * X^0の係数\r
+ * @param o_result\r
+ * 実根。double[3]を指定すること。\r
+ * @return\r
+ */\r
+ public static int solve4Equation(double i_a, double i_b, double i_c, double i_d,double i_e,double[] o_result) throws NyARException\r
+ {\r
+ assert (i_a != 0);\r
+ double A3,A2,A1,A0,B3;\r
+ A3=i_b/i_a;\r
+ A2=i_c/i_a;\r
+ A1=i_d/i_a;\r
+ A0=i_e/i_a;\r
+ B3=A3/4;\r
+ double p,q,r;\r
+ double B3_2=B3*B3;\r
+ p=A2-6*B3_2;//A2-6*B3*B3;\r
+ q=A1+B3*(-2*A2+8*B3_2);//A1-2*A2*B3+8*B3*B3*B3;\r
+ r=A0+B3*(-A1+A2*B3)-3*B3_2*B3_2;//A0-A1*B3+A2*B3*B3-3*B3*B3*B3*B3;\r
+ if(q==0){\r
+ double result_0,result_1;\r
+ //複二次式\r
+ int res=solve2Equation(p,r,o_result,0);\r
+ switch(res){\r
+ case 0:\r
+ //全て虚数解\r
+ return 0;\r
+ case 1:\r
+ //重根\r
+ //解は0,1,2の何れか。\r
+ result_0=o_result[0];\r
+ if(result_0<0){\r
+ //全て虚数解\r
+ return 0;\r
+ }\r
+ //実根1個\r
+ if(result_0==0){\r
+ //NC\r
+ o_result[0]=0-B3;\r
+ return 1;\r
+ }\r
+ //実根2個\r
+ result_0=Math.sqrt(result_0);\r
+ o_result[0]=result_0-B3;\r
+ o_result[1]=-result_0-B3;\r
+ return 2;\r
+ case 2:\r
+ //実根2個だからt==t2==0はありえない。(case1)\r
+ //解は、0,2,4の何れか。\r
+ result_0=o_result[0];\r
+ result_1=o_result[1];\r
+ int number_of_result=0;\r
+ if(result_0>0){\r
+ //NC\r
+ result_0=Math.sqrt(result_0);\r
+ o_result[0]= result_0-B3;\r
+ o_result[1]=-result_0-B3;\r
+ number_of_result+=2;\r
+ }\r
+ if(result_1>0)\r
+ {\r
+ //NC\r
+ result_1=Math.sqrt(result_1);\r
+ o_result[number_of_result+0]= result_1-B3;\r
+ o_result[number_of_result+1]=-result_1-B3;\r
+ number_of_result+=2;\r
+ }\r
+ return number_of_result;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }else{\r
+ //それ以外\r
+ //最適化ポイント:\r
+ //u^3 + (2*p)*u^2 +((- 4*r)+(p^2))*u -q^2= 0\r
+ double u=solve3Equation_1((2*p),(- 4*r)+(p*p),-q*q);\r
+ if(u<0){\r
+ //全て虚数解\r
+ return 0;\r
+ }\r
+ double ru=Math.sqrt(u);\r
+ //2次方程式を解いてyを計算(最適化ポイント)\r
+ int result_1st,result_2nd;\r
+ result_1st=solve2Equation(-ru,(p+u)/2+ru*q/(2*u),o_result,0);\r
+ //配列使い回しのために、変数に退避\r
+ switch(result_1st){\r
+ case 0:\r
+ break;\r
+ case 1:\r
+ o_result[0]=o_result[0]-B3;\r
+ break;\r
+ case 2:\r
+ o_result[0]=o_result[0]-B3;\r
+ o_result[1]=o_result[1]-B3;\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ result_2nd=solve2Equation(ru,(p+u)/2-ru*q/(2*u),o_result,result_1st);\r
+ //0,1番目に格納\r
+ switch(result_2nd){\r
+ case 0:\r
+ break;\r
+ case 1:\r
+ o_result[result_1st+0]=o_result[result_1st+0]-B3;\r
+ break;\r
+ case 2:\r
+ o_result[result_1st+0]=o_result[result_1st+0]-B3;\r
+ o_result[result_1st+1]=o_result[result_1st+1]-B3;\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ return result_1st+result_2nd;\r
+ }\r
+ }\r
+ /**\r
+ * 3乗根を求められないシステムで、3乗根を求めます。\r
+ * http://aoki2.si.gunma-u.ac.jp/JavaScript/src/3jisiki.html\r
+ * @param i_in\r
+ * @return\r
+ */\r
+ private double cuberoot(double i_in) {\r
+ double res = Math.pow(Math.abs(i_in), 1.0 / 3.0);\r
+ return (i_in >= 0) ? res : -res;\r
+ }\r
+ /**\r
+ * 3次方程式の実根を1個だけ求める。\r
+ * 4字方程式で使う。\r
+ * @param i_b\r
+ * @param i_c\r
+ * @param i_d\r
+ * @param o_result\r
+ * @return\r
+ */\r
+ private static double solve3Equation_1(double i_b, double i_c, double i_d)\r
+ {\r
+ double tmp,b, p, q;\r
+ b = i_b/(3);\r
+ p = b * b - i_c / 3;\r
+ q = (b * (i_c - 2 * b * b) - i_d) / 2;\r
+ if ((tmp = q * q - p * p * p) == 0) {\r
+ // 重根\r
+ q = Math.cbrt(q);\r
+ return 2 * q - b;\r
+ } else if (tmp > 0) {\r
+ // 実根1,虚根2\r
+ double a3 = Math.cbrt(q + ((q > 0) ? 1 : -1) * Math.sqrt(tmp));\r
+ double b3 = p / a3;\r
+ return a3 + b3 - b;\r
+ } else {\r
+ // 実根3\r
+ tmp = 2 * Math.sqrt(p);\r
+ double t = Math.acos(q / (p * tmp / 2));\r
+ return tmp * Math.cos(t / 3) - b;\r
+ }\r
+ } \r
+\r
+ public static void main(String[] args)\r
+ {\r
+ NyAREquationSolver n = new NyAREquationSolver();\r
+ int l=0;\r
+ double[] r = new double[10];\r
+ try{\r
+ l=n.solve4Equation(1, 9, -18, -68, 120, r);\r
+ }catch(Exception e){\r
+ e.printStackTrace();\r
+ }\r
+ System.out.println(l);\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+/**\r
+ * 遠近法を用いたPerspectiveパラメータを計算するクラスです。\r
+ *\r
+ */\r
+public class NyARPerspectiveParamGenerator\r
+{\r
+ protected int _local_x;\r
+ protected int _local_y;\r
+ protected int _width;\r
+ protected int _height;\r
+ public NyARPerspectiveParamGenerator(int i_local_x,int i_local_y,int i_width, int i_height)\r
+ {\r
+ this._height=i_height;\r
+ this._width=i_width;\r
+ this._local_x=i_local_x;\r
+ this._local_y=i_local_y;\r
+ return;\r
+ }\r
+ public boolean getParam(final NyARIntPoint2d[] i_vertex,double[] o_param)throws NyARException\r
+ {\r
+ double[][] la1,la2;\r
+ double[] ra1,ra2;\r
+ double ltx=this._local_x;\r
+ double lty=this._local_y;\r
+ double rbx=ltx+this._width;\r
+ double rby=lty+this._height;\r
+ la1=new double[4][5];\r
+ la2=new double[4][5];\r
+ ra1=new double[4];\r
+ ra2=new double[4];\r
+ //A,B,C,(GH)の方程式\r
+ la1[0][0]=ltx; la1[0][1]=lty; la1[0][2]=1; la1[0][3]=-ltx*i_vertex[0].x; la1[0][4]=-lty*i_vertex[0].x;\r
+ la1[1][0]=rbx; la1[1][1]=lty; la1[1][2]=1; la1[1][3]=-rbx*i_vertex[1].x; la1[1][4]=-lty*i_vertex[1].x;\r
+ la1[2][0]=rbx; la1[2][1]=rby; la1[2][2]=1; la1[2][3]=-rbx*i_vertex[2].x; la1[2][4]=-rby*i_vertex[2].x;\r
+ la1[3][0]=ltx; la1[3][1]=rby; la1[3][2]=1; la1[3][3]=-ltx*i_vertex[3].x; la1[3][4]=-rby*i_vertex[3].x;\r
+ ra1[0]=i_vertex[0].x;ra1[1]=i_vertex[1].x;ra1[2]=i_vertex[2].x;ra1[3]=i_vertex[3].x;\r
+ NyARSystemOfLinearEquationsProcessor.doGaussianElimination(la1,ra1,5,4);\r
+\r
+ //D,E,F,(GH)の方程式\r
+ la2[0][0]=ltx; la2[0][1]=lty; la2[0][2]=1; la2[0][3]=-ltx*i_vertex[0].y; la2[0][4]=-lty*i_vertex[0].y;\r
+ la2[1][0]=rbx; la2[1][1]=lty; la2[1][2]=1; la2[1][3]=-rbx*i_vertex[1].y; la2[1][4]=-lty*i_vertex[1].y;\r
+ la2[2][0]=rbx; la2[2][1]=rby; la2[2][2]=1; la2[2][3]=-rbx*i_vertex[2].y; la2[2][4]=-rby*i_vertex[2].y;\r
+ la2[3][0]=ltx; la2[3][1]=rby; la2[3][2]=1; la2[3][3]=-ltx*i_vertex[3].y; la2[3][4]=-rby*i_vertex[3].y;\r
+ ra2[0]=i_vertex[0].y;ra2[1]=i_vertex[1].y;ra2[2]=i_vertex[2].y;ra2[3]=i_vertex[3].y;\r
+ NyARSystemOfLinearEquationsProcessor.doGaussianElimination(la2,ra2,5,4);\r
+ //GHを計算\r
+ double A,B,C,D,E,F,G,H;\r
+ H=(ra2[3]-ra1[3])/(la2[3][4]-la1[3][4]);\r
+ G=ra2[3]-la2[3][4]*H;\r
+ //残りを計算\r
+ F=ra2[2]-H*la2[2][4]-G*la2[2][3];\r
+ E=ra2[1]-H*la2[1][4]-G*la2[1][3]-F*la2[1][2];\r
+ D=ra2[0]-H*la2[0][4]-G*la2[0][3]-F*la2[0][2]-E*la2[0][1];\r
+ C=ra1[2]-H*la1[2][4]-G*la1[2][3];\r
+ B=ra1[1]-H*la1[1][4]-G*la1[1][3]-C*la1[1][2];\r
+ A=ra1[0]-H*la1[0][4]-G*la1[0][3]-C*la1[0][2]-B*la1[0][1];\r
+ o_param[0]=A;\r
+ o_param[1]=B;\r
+ o_param[2]=C;\r
+ o_param[3]=D;\r
+ o_param[4]=E;\r
+ o_param[5]=F;\r
+ o_param[6]=G;\r
+ o_param[7]=H;\r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+/**\r
+ * NyARPerspectiveParamGeneratorを最適化したクラスです。\r
+ */\r
+public class NyARPerspectiveParamGenerator_O1 extends NyARPerspectiveParamGenerator\r
+{\r
+ public NyARPerspectiveParamGenerator_O1(int i_local_x,int i_local_y,int i_width, int i_height)\r
+ {\r
+ super(i_local_x,i_local_y,i_width,i_height);\r
+ this._height=i_height;\r
+ this._width=i_width;\r
+ this._local_x=i_local_x;\r
+ this._local_y=i_local_y;\r
+ return;\r
+ }\r
+ final public boolean getParam(final NyARIntPoint2d[] i_vertex,double[] o_param)throws NyARException\r
+ {\r
+ double G,H;\r
+ double w1,w2,w3,w4;\r
+ final double x0=i_vertex[0].x;\r
+ final double x1=i_vertex[1].x;\r
+ final double x2=i_vertex[2].x;\r
+ final double x3=i_vertex[3].x;\r
+ final double y0=i_vertex[0].y;\r
+ final double y1=i_vertex[1].y;\r
+ final double y2=i_vertex[2].y;\r
+ final double y3=i_vertex[3].y;\r
+ final double ltx=this._local_x;\r
+ final double lty=this._local_y;\r
+ final double rbx=ltx+this._width;\r
+ final double rby=lty+this._height;\r
+\r
+ \r
+ w1=-y3+y0;\r
+ w2= y2-y1;\r
+ final double la2_33=ltx*w1+rbx*w2;//これが0になるのはまずい。\r
+ final double la2_34=(rby*(-y3+y2)+lty*(y0-y1))/la2_33;\r
+ final double ra2_3 =(-w1-w2)/la2_33;\r
+ \r
+ w1=-x3+x0;\r
+ w2=x2-x1;\r
+ final double la1_33=ltx*w1+rbx*w2;//これが0になるのはまずい。\r
+ \r
+ //GHを計算\r
+ H=(ra2_3-((-w1-w2)/la1_33))/(la2_34-((rby*(-x3+x2)+lty*(x0-x1))/la1_33));\r
+ G=ra2_3-la2_34*H;\r
+ o_param[7]=H;\r
+ o_param[6]=G;\r
+\r
+ //残りを計算\r
+ w3=rby-lty;\r
+ w4=rbx-ltx;\r
+ w1=(y2-y1-H*(-rby*y2+lty*y1)-G*(-rbx*y2+rbx*y1))/w3;\r
+ w2=(y1-y0-H*(-lty*y1+lty*y0)-G*(-rbx*y1+ltx*y0))/w4;\r
+ o_param[5]=y0*(1+H*lty+G*ltx)-w1*lty-w2*ltx;\r
+ o_param[4]=w1;\r
+ o_param[3]=w2;\r
+ \r
+ \r
+ w1=(x2-x1-H*(-rby*x2+lty*x1)-G*(-rbx*x2+rbx*x1))/w3;\r
+ w2=(x1-x0-H*(-lty*x1+lty*x0)-G*(-rbx*x1+ltx*x0))/w4;\r
+ o_param[2]=x0*(1+H*lty+G*ltx)-w1*lty-w2*ltx;\r
+ o_param[1]=w1;\r
+ o_param[0]=w2;\r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.core.utils;\r
+\r
+/**\r
+ * 連立方程式を解くためのプロセッサクラスです。\r
+ *\r
+ */\r
+public class NyARSystemOfLinearEquationsProcessor\r
+{\r
+ /**\r
+ * i_reftとi_rightの整合性を確認します。\r
+ * @param i_left\r
+ * @param i_right\r
+ * @return\r
+ */\r
+ private static boolean isValid2dArray(double[][] i_left,double[] i_right)\r
+ { \r
+ final int sm=i_left.length;\r
+ final int sn=i_left[0].length;\r
+ if(i_left.length!=sm){\r
+ return false;\r
+ }\r
+ if(i_right.length!=sm){\r
+ return false;\r
+ }\r
+ for(int i=1;i<sm;i++){\r
+ if(i_left[i].length!=sn){\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * [i_left_src]=[i_right_src]の式にガウスの消去法を実行して、[x][x]の要素が1になるように基本変形します。\r
+ * i_mとi_nが等しくない時は、最終行までの[x][x]要素までを1になるように変形します。\r
+ * @param i_left\r
+ * 連立方程式の左辺値を指定します。[i_m][i_n]の配列を指定してください。\r
+ * @param i_right\r
+ * 連立方程式の右辺値を指定します。[i_m][i_n]の配列を指定してください。\r
+ * @param i_n\r
+ * 連立方程式の係数の数を指定します。\r
+ * @param i_m\r
+ * 連立方程式の数を指定します。\r
+ * @return\r
+ * 最終行まで基本変形ができてばtrueを返します。\r
+ */\r
+ public static boolean doGaussianElimination(double[][] i_left,double[] i_right,int i_n,int i_m)\r
+ {\r
+ //整合性を確認する.\r
+ assert isValid2dArray(i_left,i_right);\r
+ \r
+\r
+ //1行目以降\r
+ for(int solve_row=0;solve_row<i_m;solve_row++)\r
+ {\r
+ {//ピボット操作\r
+ int pivod=solve_row;\r
+ double pivod_value=Math.abs(i_left[pivod][pivod]);\r
+ for(int i=solve_row+1;i<i_m;i++){\r
+ final double pivod_2=Math.abs(i_left[i][pivod]);\r
+ if(pivod_value<Math.abs(pivod_2)){\r
+ pivod=i;\r
+ pivod_value=pivod_2;\r
+ }\r
+ }\r
+ if(solve_row!=pivod){\r
+ //行の入れ替え(Cの時はポインタテーブル使って!)\r
+ final double[] t=i_left[solve_row];\r
+ i_left[solve_row]=i_left[pivod];\r
+ i_left[pivod]=t;\r
+ final double t2=i_right[solve_row];\r
+ i_right[solve_row]=i_right[pivod];\r
+ i_right[pivod]=t2;\r
+ }\r
+ }\r
+ final double[] dest_l_n=i_left[solve_row];\r
+ final double dest_l_nn=i_left[solve_row][solve_row];\r
+ if(dest_l_nn==0.0){\r
+ //選択後の対角要素が0になってしまったら失敗する。\r
+ return false;\r
+ } \r
+\r
+ //消去計算(0 - solve_row-1項までの消去)\r
+ for(int i=0;i<solve_row;i++){\r
+ double s=dest_l_n[i];\r
+ for(int i2=0;i2<i_n;i2++)\r
+ {\r
+ final double p=i_left[i][i2]*s;\r
+ dest_l_n[i2]=dest_l_n[i2]-p;\r
+ }\r
+ final double k=i_right[i]*s;\r
+ i_right[solve_row]=i_right[solve_row]-k;\r
+ \r
+ }\r
+ //消去法の実行(割り算)\r
+ final double d=dest_l_n[solve_row];\r
+ for(int i2=0;i2<solve_row;i2++){\r
+ dest_l_n[i2]=0;\r
+ }\r
+ if(d!=1.0){\r
+ dest_l_n[solve_row]=1.0;\r
+ for(int i=solve_row+1;i<i_n;i++){\r
+ dest_l_n[i]/=d;\r
+ }\r
+ i_right[solve_row]/=d;\r
+ }\r
+ }\r
+ return true; \r
+ }\r
+ /**\r
+ * i_leftとi_rightの連立方程式を解いて、i_left,i_right内容を更新します。\r
+ * i_right[n]の内容が、i_left[x][n]番目の係数の解になります。\r
+ * @return\r
+ * 方程式が解ければtrueを返します。\r
+ */\r
+ public static boolean solve(double[][] i_left,double[] i_right,int i_number_of_system)\r
+ {\r
+ return doGaussianElimination(i_left,i_right,i_number_of_system,i_number_of_system);\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.detector;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+\r
+/**\r
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。\r
+ * 変換行列を求めるには、detectMarkerLite関数にラスタイメージを入力して、計算対象の矩形を特定します。\r
+ * detectMarkerLiteが成功すると、getTransmationMatrix等の関数が使用可能な状態になり、変換行列を求めることができます。\r
+ * \r
+ * \r
+ */\r
+public class NyARCustomSingleDetectMarker\r
+{\r
+ /**\r
+ * detectMarkerのコールバック関数\r
+ */\r
+ private class DetectSquareCB implements INyARSquareContourDetector.DetectMarkerCallback\r
+ {\r
+ //公開プロパティ\r
+ public double confidence;\r
+ public NyARSquare square=new NyARSquare();\r
+ \r
+ //参照インスタンス\r
+ private INyARRgbRaster _ref_raster;\r
+ //所有インスタンス\r
+ private INyARColorPatt _inst_patt;\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA _match_patt;\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ private Coord2Linear _coordline;\r
+ \r
+ public DetectSquareCB(INyARColorPatt i_inst_patt,NyARCode i_ref_code,NyARParam i_param)\r
+ {\r
+ this._inst_patt=i_inst_patt;\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(i_ref_code.getWidth(),i_ref_code.getHeight());\r
+ this._coordline=new Coord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+ this._match_patt=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code);\r
+ return;\r
+ }\r
+ private NyARIntPoint2d[] __tmp_vertex=NyARIntPoint2d.createArray(4);\r
+ /**\r
+ * 矩形が見付かるたびに呼び出されます。\r
+ * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+ */\r
+ public void onSquareDetect(INyARSquareContourDetector i_sender,int[] i_coordx,int[] i_coordy,int i_coor_num,int[] i_vertex_index) throws NyARException\r
+ {\r
+ NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+ //輪郭座標から頂点リストに変換\r
+ NyARIntPoint2d[] vertex=this.__tmp_vertex;\r
+ vertex[0].x=i_coordx[i_vertex_index[0]];\r
+ vertex[0].y=i_coordy[i_vertex_index[0]];\r
+ vertex[1].x=i_coordx[i_vertex_index[1]];\r
+ vertex[1].y=i_coordy[i_vertex_index[1]];\r
+ vertex[2].x=i_coordx[i_vertex_index[2]];\r
+ vertex[2].y=i_coordy[i_vertex_index[2]];\r
+ vertex[3].x=i_coordx[i_vertex_index[3]];\r
+ vertex[3].y=i_coordy[i_vertex_index[3]];\r
+ \r
+ //画像を取得\r
+ if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){\r
+ return;\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._inst_patt);\r
+ if(!this._match_patt.evaluate(this._deviation_data,mr)){\r
+ return;\r
+ }\r
+ //現在の一致率より低ければ終了\r
+ if (this.confidence > mr.confidence){\r
+ return;\r
+ }\r
+ //一致率の高い矩形があれば、方位を考慮して頂点情報を作成\r
+ NyARSquare sq=this.square;\r
+ this.confidence = mr.confidence;\r
+ //directionを考慮して、squareを更新する。\r
+ for(int i=0;i<4;i++){\r
+ int idx=(i+4 - mr.direction) % 4;\r
+ sq.imvertex[i].x=vertex[idx].x;\r
+ sq.imvertex[i].y=vertex[idx].y;\r
+ this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);\r
+ }\r
+ for (int i = 0; i < 4; i++) {\r
+ //直線同士の交点計算\r
+ if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+ throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+ }\r
+ }\r
+ }\r
+ public final void init(INyARRgbRaster i_raster)\r
+ {\r
+ this.confidence=0;\r
+ this._ref_raster=i_raster;\r
+ \r
+ }\r
+ }\r
+ \r
+ private boolean _is_continue = false;\r
+ private INyARSquareContourDetector _square_detect;\r
+ protected INyARTransMat _transmat;\r
+ private double _marker_width;\r
+ //画処理用\r
+ private NyARBinRaster _bin_raster;\r
+ protected INyARRasterFilter_RgbToBin _tobin_filter;\r
+ private DetectSquareCB _detect_cb;\r
+\r
+\r
+ protected NyARCustomSingleDetectMarker()\r
+ {\r
+ return;\r
+ }\r
+ protected void initInstance(\r
+ INyARColorPatt i_patt_inst,\r
+ INyARSquareContourDetector i_sqdetect_inst,\r
+ INyARTransMat i_transmat_inst,\r
+ INyARRasterFilter_RgbToBin i_filter,\r
+ NyARParam i_ref_param,\r
+ NyARCode i_ref_code,\r
+ double i_marker_width) throws NyARException\r
+ {\r
+ final NyARIntSize scr_size=i_ref_param.getScreenSize(); \r
+ // 解析オブジェクトを作る\r
+ this._square_detect = i_sqdetect_inst;\r
+ this._transmat = i_transmat_inst;\r
+ this._tobin_filter=i_filter;\r
+ // 比較コードを保存\r
+ this._marker_width = i_marker_width;\r
+ //2値画像バッファを作る\r
+ this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
+ //_detect_cb\r
+ this._detect_cb=new DetectSquareCB(i_patt_inst,i_ref_code,i_ref_param);\r
+ return;\r
+ \r
+ }\r
+\r
+ \r
+\r
+ \r
+ /**\r
+ * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+ * \r
+ * @param i_raster\r
+ * マーカーを検出するイメージを指定します。イメージサイズは、カメラパラメータ\r
+ * と一致していなければなりません。\r
+ * @return マーカーが検出できたかを真偽値で返します。\r
+ * @throws NyARException\r
+ */\r
+ public boolean detectMarkerLite(INyARRgbRaster i_raster) throws NyARException\r
+ {\r
+ //サイズチェック\r
+ if(!this._bin_raster.getSize().isEqualSize(i_raster.getSize())){\r
+ throw new NyARException();\r
+ }\r
+\r
+ //ラスタを2値イメージに変換する.\r
+ this._tobin_filter.doFilter(i_raster,this._bin_raster);\r
+\r
+ //コールバックハンドラの準備\r
+ this._detect_cb.init(i_raster);\r
+ //矩形を探す(戻り値はコールバック関数で受け取る。)\r
+ this._square_detect.detectMarkerCB(this._bin_raster,_detect_cb);\r
+ if(this._detect_cb.confidence==0){\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。\r
+ * 直前に実行したdetectMarkerLiteが成功していないと使えません。\r
+ * \r
+ * @param o_result\r
+ * 変換行列を受け取るオブジェクトを指定します。\r
+ * @throws NyARException\r
+ */\r
+ public void getTransmationMatrix(NyARTransMatResult o_result) throws NyARException\r
+ {\r
+ // 一番一致したマーカーの位置とかその辺を計算\r
+ if (this._is_continue) {\r
+ this._transmat.transMatContinue(this._detect_cb.square,this._marker_width, o_result);\r
+ } else {\r
+ this._transmat.transMat(this._detect_cb.square,this._marker_width, o_result);\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * 画面上のマーカ頂点情報を配列へ取得します。\r
+ * @param o_point\r
+ * 4要素以上の配列を指定して下さい。先頭の4要素に値がコピーされます。\r
+ */\r
+ public void getSquarePosition(NyARIntPoint2d[] o_point)\r
+ {\r
+ NyARIntPoint2d.copyArray(this._detect_cb.square.imvertex,o_point);\r
+ return;\r
+ }\r
+ /**\r
+ * 画面上のマーカ頂点情報を配列へのリファレンスを返します。\r
+ * 返されたオブジェクトはクラスに所有し続けられています。クラスのメンバ関数を実行すると内容が書き変わります。\r
+ * 外部でデータをストックする場合は、getSquarePositionで複製して下さい。\r
+ * @return\r
+ */\r
+ public NyARIntPoint2d[] refSquarePosition()\r
+ {\r
+ return this._detect_cb.square.imvertex;\r
+ }\r
+ \r
+\r
+ /**\r
+ * 検出したマーカーの一致度を返します。\r
+ * \r
+ * @return マーカーの一致度を返します。0~1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。\r
+ * @throws NyARException\r
+ */\r
+ public double getConfidence()\r
+ {\r
+ return this._detect_cb.confidence;\r
+ }\r
+ /**\r
+ * getTransmationMatrixの計算モードを設定します。 初期値はTRUEです。\r
+ * \r
+ * @param i_is_continue\r
+ * TRUEなら、transMatCont互換の計算をします。 FALSEなら、transMat互換の計算をします。\r
+ */\r
+ public void setContinueMode(boolean i_is_continue)\r
+ {\r
+ this._is_continue = i_is_continue;\r
+ }\r
+ \r
+ \r
+ \r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.detector;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.Coord2Linear;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareContourDetector;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareContourDetector_Rle;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.stack.NyObjectStack;\r
+\r
+class NyARDetectMarkerResult\r
+{\r
+ public int arcode_id;\r
+ public double confidence;\r
+\r
+ public NyARSquare square=new NyARSquare();\r
+}\r
+\r
+\r
+class NyARDetectMarkerResultStack extends NyObjectStack<NyARDetectMarkerResult>\r
+{\r
+ public NyARDetectMarkerResultStack(int i_length)\r
+ {\r
+ super(i_length,NyARDetectMarkerResult.class);\r
+ return;\r
+ }\r
+ protected NyARDetectMarkerResult createElement()\r
+ {\r
+ return new NyARDetectMarkerResult();\r
+ } \r
+}\r
+\r
+\r
+/**\r
+ * 複数のマーカーを検出し、それぞれに最も一致するARコードを、コンストラクタで登録したARコードから 探すクラスです。最大300個を認識しますが、ゴミラベルを認識したりするので100個程度が限界です。\r
+ * \r
+ */\r
+public class NyARDetectMarker\r
+{\r
+ /**\r
+ * detectMarkerのコールバック関数\r
+ */\r
+ private class DetectSquareCB implements INyARSquareContourDetector.DetectMarkerCallback\r
+ {\r
+ //公開プロパティ\r
+ public NyARDetectMarkerResultStack result_stack=new NyARDetectMarkerResultStack(NyARDetectMarker.AR_SQUARE_MAX);\r
+ //参照インスタンス\r
+ public INyARRgbRaster _ref_raster;\r
+ //所有インスタンス\r
+ private INyARColorPatt _inst_patt;\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA[] _match_patt;\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ private Coord2Linear _coordline;\r
+ \r
+ public DetectSquareCB(INyARColorPatt i_inst_patt,NyARCode[] i_ref_code,int i_num_of_code,NyARParam i_param) throws NyARException\r
+ {\r
+ final int cw = i_ref_code[0].getWidth();\r
+ final int ch = i_ref_code[0].getHeight();\r
+\r
+ this._inst_patt=i_inst_patt;\r
+ this._coordline=new Coord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(cw,ch);\r
+\r
+ //NyARMatchPatt_Color_WITHOUT_PCA[]の作成\r
+ this._match_patt=new NyARMatchPatt_Color_WITHOUT_PCA[i_num_of_code];\r
+ this._match_patt[0]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[0]);\r
+ for (int i = 1; i < i_num_of_code; i++){\r
+ //解像度チェック\r
+ if (cw != i_ref_code[i].getWidth() || ch != i_ref_code[i].getHeight()) {\r
+ throw new NyARException();\r
+ }\r
+ this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]);\r
+ }\r
+ return;\r
+ }\r
+ private NyARIntPoint2d[] __tmp_vertex=NyARIntPoint2d.createArray(4);\r
+ /**\r
+ * 矩形が見付かるたびに呼び出されます。\r
+ * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+ */\r
+ public void onSquareDetect(INyARSquareContourDetector i_sender,int[] i_coordx,int[] i_coordy,int i_coor_num,int[] i_vertex_index) throws NyARException\r
+ {\r
+ NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+ //輪郭座標から頂点リストに変換\r
+ NyARIntPoint2d[] vertex=this.__tmp_vertex;\r
+ vertex[0].x=i_coordx[i_vertex_index[0]];\r
+ vertex[0].y=i_coordy[i_vertex_index[0]];\r
+ vertex[1].x=i_coordx[i_vertex_index[1]];\r
+ vertex[1].y=i_coordy[i_vertex_index[1]];\r
+ vertex[2].x=i_coordx[i_vertex_index[2]];\r
+ vertex[2].y=i_coordy[i_vertex_index[2]];\r
+ vertex[3].x=i_coordx[i_vertex_index[3]];\r
+ vertex[3].y=i_coordy[i_vertex_index[3]];\r
+ \r
+ //画像を取得\r
+ if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){\r
+ return;\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._inst_patt);\r
+\r
+ //最も一致するパターンを割り当てる。\r
+ int square_index,direction;\r
+ double confidence;\r
+ this._match_patt[0].evaluate(this._deviation_data,mr);\r
+ square_index=0;\r
+ direction=mr.direction;\r
+ confidence=mr.confidence;\r
+ //2番目以降\r
+ for(int i=1;i<this._match_patt.length;i++){\r
+ this._match_patt[i].evaluate(this._deviation_data,mr);\r
+ if (confidence > mr.confidence) {\r
+ continue;\r
+ }\r
+ // もっと一致するマーカーがあったぽい\r
+ square_index = i;\r
+ direction = mr.direction;\r
+ confidence = mr.confidence;\r
+ }\r
+ //最も一致したマーカ情報を、この矩形の情報として記録する。\r
+ final NyARDetectMarkerResult result = this.result_stack.prePush();\r
+ result.arcode_id = square_index;\r
+ result.confidence = confidence;\r
+\r
+ final NyARSquare sq=result.square;\r
+ //directionを考慮して、squareを更新する。\r
+ for(int i=0;i<4;i++){\r
+ int idx=(i+4 - direction) % 4;\r
+ sq.imvertex[i].x=vertex[idx].x;\r
+ sq.imvertex[i].y=vertex[idx].y;\r
+ this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);\r
+ }\r
+ for (int i = 0; i < 4; i++) {\r
+ //直線同士の交点計算\r
+ if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+ throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+ }\r
+ }\r
+ }\r
+ public void init(INyARRgbRaster i_raster)\r
+ {\r
+ this._ref_raster=i_raster;\r
+ this.result_stack.clear();\r
+ \r
+ }\r
+ } \r
+ private DetectSquareCB _detect_cb;\r
+ \r
+ \r
+ private static final int AR_SQUARE_MAX = 300;\r
+ private boolean _is_continue = false;\r
+ private INyARSquareContourDetector _square_detect;\r
+ protected INyARTransMat _transmat;\r
+ private double[] _marker_width; \r
+\r
+\r
+ /**\r
+ * 複数のマーカーを検出し、最も一致するARCodeをi_codeから検索するオブジェクトを作ります。\r
+ * \r
+ * @param i_param\r
+ * カメラパラメータを指定します。\r
+ * @param i_code\r
+ * 検出するマーカーのARCode配列を指定します。\r
+ * 配列要素のインデックス番号が、そのままgetARCodeIndex関数で得られるARCodeインデックスになります。 \r
+ * 例えば、要素[1]のARCodeに一致したマーカーである場合は、getARCodeIndexは1を返します。\r
+ * @param i_marker_width\r
+ * i_codeのマーカーサイズをミリメートルで指定した配列を指定します。 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。\r
+ * @param i_number_of_code\r
+ * i_codeに含まれる、ARCodeの数を指定します。\r
+ * @param i_input_raster_type\r
+ * 入力ラスタのピクセルタイプを指定します。この値は、INyARBufferReaderインタフェイスのgetBufferTypeの戻り値を指定します。\r
+ * @throws NyARException\r
+ */\r
+ public NyARDetectMarker(NyARParam i_param,NyARCode[] i_code,double[] i_marker_width, int i_number_of_code,int i_input_raster_type) throws NyARException\r
+ {\r
+ initInstance(i_param,i_code,i_marker_width,i_number_of_code,i_input_raster_type);\r
+ return;\r
+ }\r
+ protected void initInstance(\r
+ NyARParam i_ref_param,\r
+ NyARCode[] i_ref_code,\r
+ double[] i_marker_width,\r
+ int i_number_of_code,\r
+ int i_input_raster_type) throws NyARException\r
+ {\r
+\r
+ final NyARIntSize scr_size=i_ref_param.getScreenSize();\r
+ // 解析オブジェクトを作る\r
+ final int cw = i_ref_code[0].getWidth();\r
+ final int ch = i_ref_code[0].getHeight();\r
+\r
+ //detectMarkerのコールバック関数\r
+ this._detect_cb=new DetectSquareCB(\r
+ new NyARColorPatt_Perspective_O2(cw, ch,4,25),\r
+ i_ref_code,i_number_of_code,i_ref_param);\r
+ this._transmat = new NyARTransMat(i_ref_param);\r
+ //NyARToolkitプロファイル\r
+ this._square_detect =new NyARSquareContourDetector_Rle(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
+ this._tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100,i_input_raster_type);\r
+\r
+ //実サイズ保存\r
+ this._marker_width = i_marker_width;\r
+ //2値画像バッファを作る\r
+ this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);\r
+ return; \r
+ }\r
+ \r
+ private NyARBinRaster _bin_raster;\r
+\r
+ private INyARRasterFilter_RgbToBin _tobin_filter;\r
+\r
+ /**\r
+ * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+ * \r
+ * @param i_raster\r
+ * マーカーを検出するイメージを指定します。\r
+ * @param i_thresh\r
+ * 検出閾値を指定します。0~255の範囲で指定してください。 通常は100~130くらいを指定します。\r
+ * @return 見つかったマーカーの数を返します。 マーカーが見つからない場合は0を返します。\r
+ * @throws NyARException\r
+ */\r
+ public int detectMarkerLite(INyARRgbRaster i_raster, int i_threshold) throws NyARException\r
+ {\r
+ // サイズチェック\r
+ if (!this._bin_raster.getSize().isEqualSize(i_raster.getSize())) {\r
+ throw new NyARException();\r
+ }\r
+\r
+ // ラスタを2値イメージに変換する.\r
+ ((NyARRasterFilter_ARToolkitThreshold)this._tobin_filter).setThreshold(i_threshold);\r
+ this._tobin_filter.doFilter(i_raster, this._bin_raster);\r
+\r
+ //detect\r
+ this._detect_cb.init(i_raster);\r
+ this._square_detect.detectMarkerCB(this._bin_raster,this._detect_cb);\r
+\r
+ //見付かった数を返す。\r
+ return this._detect_cb.result_stack.getLength();\r
+ }\r
+\r
+ /**\r
+ * i_indexのマーカーに対する変換行列を計算し、結果値をo_resultへ格納します。 直前に実行したdetectMarkerLiteが成功していないと使えません。\r
+ * \r
+ * @param i_index\r
+ * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
+ * @param o_result\r
+ * 結果値を受け取るオブジェクトを指定してください。\r
+ * @throws NyARException\r
+ */\r
+ public void getTransmationMatrix(int i_index, NyARTransMatResult o_result) throws NyARException\r
+ {\r
+ final NyARDetectMarkerResult result = this._detect_cb.result_stack.getItem(i_index);\r
+ // 一番一致したマーカーの位置とかその辺を計算\r
+ if (_is_continue) {\r
+ _transmat.transMatContinue(result.square, _marker_width[result.arcode_id], o_result);\r
+ } else {\r
+ _transmat.transMat(result.square, _marker_width[result.arcode_id], o_result);\r
+ }\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * i_indexのマーカーの一致度を返します。\r
+ * \r
+ * @param i_index\r
+ * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
+ * @return マーカーの一致度を返します。0~1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。\r
+ * @throws NyARException\r
+ */\r
+ public double getConfidence(int i_index)\r
+ {\r
+ return this._detect_cb.result_stack.getItem(i_index).confidence;\r
+ }\r
+ /**\r
+ * i_indexのマーカーのARCodeインデックスを返します。\r
+ * \r
+ * @param i_index\r
+ * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。\r
+ * @return\r
+ */\r
+ public int getARCodeIndex(int i_index)\r
+ {\r
+ return this._detect_cb.result_stack.getItem(i_index).arcode_id;\r
+ }\r
+\r
+ /**\r
+ * getTransmationMatrixの計算モードを設定します。\r
+ * \r
+ * @param i_is_continue\r
+ * TRUEなら、transMatContinueを使用します。 FALSEなら、transMatを使用します。\r
+ */\r
+ public void setContinueMode(boolean i_is_continue)\r
+ {\r
+ this._is_continue = i_is_continue;\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.detector;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.pickup.INyARColorPatt;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilter_ARToolkitThreshold;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+/**\r
+ * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。\r
+ * \r
+ */\r
+public class NyARSingleDetectMarker extends NyARCustomSingleDetectMarker\r
+{\r
+ public final static int PF_ARTOOLKIT_COMPATIBLE=1;\r
+ public final static int PF_NYARTOOLKIT=2;\r
+ public final static int PF_NYARTOOLKIT_ARTOOLKIT_FITTING=100;\r
+ public final static int PF_TEST2=201;\r
+ \r
+ /**\r
+ * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。\r
+ * \r
+ * @param i_param\r
+ * カメラパラメータを指定します。\r
+ * @param i_code\r
+ * 検出するARCodeを指定します。\r
+ * @param i_marker_width\r
+ * ARコードの物理サイズを、ミリメートルで指定します。\r
+ * @param i_input_raster_type\r
+ * 入力ラスタのピクセルタイプを指定します。この値は、INyARBufferReaderインタフェイスのgetBufferTypeの戻り値を指定します。\r
+ * @throws NyARException\r
+ */\r
+ public NyARSingleDetectMarker(NyARParam i_param, NyARCode i_code, double i_marker_width,int i_input_raster_type,int i_profile_id) throws NyARException\r
+ {\r
+ super();\r
+ initInstance(i_param,i_code,i_marker_width,i_input_raster_type,i_profile_id);\r
+ return;\r
+ }\r
+ public NyARSingleDetectMarker(NyARParam i_param, NyARCode i_code, double i_marker_width,int i_input_raster_type) throws NyARException\r
+ {\r
+ super();\r
+ initInstance(i_param,i_code,i_marker_width,i_input_raster_type,PF_NYARTOOLKIT);\r
+ return;\r
+ }\r
+ /**\r
+ * コンストラクタから呼び出す関数です。\r
+ * @param i_ref_param\r
+ * @param i_ref_code\r
+ * @param i_marker_width\r
+ * @param i_input_raster_type\r
+ * @param i_profile_id\r
+ * @throws NyARException\r
+ */\r
+ protected void initInstance(\r
+ NyARParam i_ref_param,\r
+ NyARCode i_ref_code,\r
+ double i_marker_width,\r
+ int i_input_raster_type,\r
+ int i_profile_id) throws NyARException\r
+ {\r
+ final NyARRasterFilter_ARToolkitThreshold th=new NyARRasterFilter_ARToolkitThreshold(100,i_input_raster_type);\r
+ INyARColorPatt patt_inst;\r
+ INyARSquareContourDetector sqdetect_inst;\r
+ INyARTransMat transmat_inst;\r
+\r
+ switch(i_profile_id){\r
+ case PF_ARTOOLKIT_COMPATIBLE:\r
+ patt_inst=new NyARColorPatt_O3(i_ref_code.getWidth(), i_ref_code.getHeight());\r
+ sqdetect_inst=new NyARSquareContourDetector_ARToolKit(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
+ transmat_inst=new NyARTransMat_ARToolKit(i_ref_param);\r
+ break;\r
+ case PF_NYARTOOLKIT_ARTOOLKIT_FITTING:\r
+ patt_inst=new NyARColorPatt_Perspective_O2(i_ref_code.getWidth(), i_ref_code.getHeight(),4,25);\r
+ sqdetect_inst=new NyARSquareContourDetector_Rle(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
+ transmat_inst=new NyARTransMat_ARToolKit(i_ref_param);\r
+ break;\r
+ case PF_NYARTOOLKIT://default\r
+ patt_inst=new NyARColorPatt_Perspective_O2(i_ref_code.getWidth(), i_ref_code.getHeight(),4,25);\r
+ sqdetect_inst=new NyARSquareContourDetector_Rle(i_ref_param.getDistortionFactor(),i_ref_param.getScreenSize());\r
+ transmat_inst=new NyARTransMat(i_ref_param);\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ super.initInstance(patt_inst,sqdetect_inst,transmat_inst,th,i_ref_param,i_ref_code,i_marker_width);\r
+ \r
+ }\r
+\r
+ /**\r
+ * i_imageにマーカー検出処理を実行し、結果を記録します。\r
+ * \r
+ * @param i_raster\r
+ * マーカーを検出するイメージを指定します。イメージサイズは、コンストラクタで指定i_paramの\r
+ * スクリーンサイズと一致し、かつi_input_raster_typeに指定した形式でなければいけません。\r
+ * @return マーカーが検出できたかを真偽値で返します。\r
+ * @throws NyARException\r
+ */\r
+ public boolean detectMarkerLite(INyARRgbRaster i_raster,int i_threshold) throws NyARException\r
+ {\r
+ ((NyARRasterFilter_ARToolkitThreshold)this._tobin_filter).setThreshold(i_threshold);\r
+ return super.detectMarkerLite(i_raster);\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker;\r
+\r
+/**\r
+ * [[Strage class]]\r
+ * マーカを抽出した時のパラメータを格納するクラスです。\r
+ *\r
+ */\r
+public class NyIdMarkerParam\r
+{\r
+ /**\r
+ * マーカの方位値です。\r
+ */\r
+ public int direction;\r
+ /**\r
+ * マーカ周辺のパターン閾値です。\r
+ */\r
+ public int threshold; \r
+ \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker;\r
+/**\r
+ * [[Strage class]]\r
+ * IDマーカパターン値を格納するクラスです。\r
+ * クラスは、未整形のマーカデータを格納しています。\r
+ *\r
+ */\r
+public class NyIdMarkerPattern\r
+{\r
+ public int model;\r
+ public int ctrl_domain;\r
+ public int ctrl_mask;\r
+ public int check;\r
+ public final int[] data=new int[32];\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.utils.*;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * NyARColorPatt_NyIdMarkerがラスタからPerspective変換して読みだすためのクラス\r
+ *\r
+ */\r
+class PerspectivePixelReader\r
+{\r
+ private NyARPerspectiveParamGenerator _param_gen=new NyARPerspectiveParamGenerator_O1(1,1,100,100);\r
+ private double[] _cparam=new double[8];\r
+\r
+\r
+ public PerspectivePixelReader()\r
+ {\r
+ return;\r
+ }\r
+\r
+ public boolean setSourceSquare(NyARIntPoint2d[] i_vertex)throws NyARException\r
+ {\r
+ return this._param_gen.getParam(i_vertex, this._cparam);\r
+ }\r
+\r
+ /**\r
+ * 矩形からピクセルを切り出します\r
+ * @param i_lt_x\r
+ * @param i_lt_y\r
+ * @param i_step_x\r
+ * @param i_step_y\r
+ * @param i_width\r
+ * @param i_height\r
+ * @param i_out_st\r
+ * o_pixelへの格納場所の先頭インデクス\r
+ * @param o_pixel\r
+ * @throws NyARException\r
+ */\r
+ private boolean rectPixels(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,int i_lt_x,int i_lt_y,int i_step_x,int i_step_y,int i_width,int i_height,int i_out_st,int[] o_pixel)throws NyARException\r
+ {\r
+ final double[] cpara=this._cparam;\r
+ final int[] ref_x=this._ref_x;\r
+ final int[] ref_y=this._ref_y;\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+ final int raster_width=i_raster_size.w;\r
+ final int raster_height=i_raster_size.h;\r
+\r
+ int out_index=i_out_st;\r
+ final double cpara_6=cpara[6];\r
+ final double cpara_0=cpara[0];\r
+ final double cpara_3=cpara[3];\r
+\r
+ for(int i=0;i<i_height;i++){\r
+ //1列分のピクセルのインデックス値を計算する。\r
+ int cy0=1+i*i_step_y+i_lt_y;\r
+ double cpy0_12=cpara[1]*cy0+cpara[2];\r
+ double cpy0_45=cpara[4]*cy0+cpara[5];\r
+ double cpy0_7=cpara[7]*cy0+1.0; \r
+ int pt=0;\r
+ for(int i2=0;i2<i_width;i2++)\r
+ {\r
+ final int cx0=1+i2*i_step_x+i_lt_x; \r
+ final double d=cpara_6*cx0+cpy0_7;\r
+ final int x=(int)((cpara_0*cx0+cpy0_12)/d);\r
+ final int y=(int)((cpara_3*cx0+cpy0_45)/d);\r
+ if(x<0||y<0||x>=raster_width||y>=raster_height)\r
+ {\r
+ return false;\r
+ }\r
+ ref_x[pt]=x;\r
+ ref_y[pt]=y;\r
+ pt++;\r
+ }\r
+ //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+ i_reader.getPixelSet(ref_x,ref_y,i_width,pixcel_temp);\r
+ //グレースケールにしながら、line→mapへの転写\r
+ for(int i2=0;i2<i_width;i2++){\r
+ int index=i2*3;\r
+ o_pixel[out_index]=(pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2])/3;\r
+ out_index++;\r
+ } \r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * i_freqにあるゼロクロス点の周期が、等間隔か調べます。\r
+ * 次段半周期が、前段の80%より大きく、120%未満であるものを、等間隔周期であるとみなします。\r
+ * @param i_freq\r
+ * @param i_width\r
+ */\r
+ private static boolean checkFreqWidth(int[] i_freq,int i_width)\r
+ {\r
+ int c=i_freq[1]-i_freq[0];\r
+ final int count=i_width*2-1;\r
+ for(int i=1;i<count;i++){\r
+ final int n=i_freq[i+1]-i_freq[i];\r
+ final int v=n*100/c;\r
+ if(v>150 || v<50){\r
+ return false;\r
+ }\r
+ c=n;\r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * i_freq_count_tableとi_freq_tableの内容を調査し、最も大きな周波数成分を返します。\r
+ * @param i_freq_count_table\r
+ * @param i_freq_table\r
+ * @param o_freq_table\r
+ * @return\r
+ * 見つかれば0以上、密辛ければ0未満\r
+ */\r
+ private static int getMaxFreq(int[] i_freq_count_table,int[] i_freq_table,int[] o_freq_table)\r
+ {\r
+ //一番成分の大きいものを得る\r
+ int index=-1;\r
+ int max=0;\r
+ for(int i=0;i<MAX_FREQ;i++){\r
+ if(max<i_freq_count_table[i]){\r
+ index=i;\r
+ max=i_freq_count_table[i];\r
+ }\r
+ } \r
+ if(index==-1){\r
+ return -1;\r
+ }\r
+ /*周波数インデクスを計算*/\r
+ final int st=(index-1)*index;\r
+ for(int i=0;i<index*2;i++)\r
+ {\r
+ o_freq_table[i]=i_freq_table[st+i]*FRQ_STEP/max;\r
+ }\r
+ return index;\r
+ }\r
+ \r
+ \r
+ //タイミングパターン用のパラメタ(FRQ_POINTS*FRQ_STEPが100を超えないようにすること)\r
+ private static final int FRQ_EDGE=5;\r
+ private static final int FRQ_STEP=2;\r
+ private static final int FRQ_POINTS=(100-(FRQ_EDGE*2))/FRQ_STEP;\r
+ \r
+\r
+ private static final int MIN_FREQ=3;\r
+ private static final int MAX_FREQ=10;\r
+ private static final int FREQ_SAMPLE_NUM=4;\r
+ private static final int MAX_DATA_BITS=MAX_FREQ+MAX_FREQ-1;\r
+\r
+ private final int[] _ref_x=new int[108];\r
+ private final int[] _ref_y=new int[108];\r
+ //(model+1)*4*3とTHRESHOLD_PIXEL*3のどちらか大きい方\r
+ private int[] _pixcel_temp=new int[108*3];\r
+ \r
+ private final int[] _freq_count_table=new int[MAX_FREQ];\r
+ private final int[] _freq_table=new int[(MAX_FREQ*2-1)*MAX_FREQ*2/2];\r
+\r
+ /**\r
+ * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。\r
+ * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを\r
+ * 検出した場合、関数は失敗します。\r
+ * \r
+ * @param i_y1\r
+ * @param i_y2\r
+ * @param i_th_h\r
+ * @param i_th_l\r
+ * @param o_edge_index\r
+ * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。\r
+ * [FRQ_POINTS]以上の配列を指定してください。\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public int getRowFrequency(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,int i_y1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+ {\r
+ //3,4,5,6,7,8,9,10\r
+ final int[] freq_count_table=this._freq_count_table;\r
+ //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列\r
+ final int freq_table[]=this._freq_table;\r
+ //初期化\r
+ final double[] cpara=this._cparam;\r
+// final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+ final int[] ref_x=this._ref_x;\r
+ final int[] ref_y=this._ref_y;\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+ for(int i=0;i<10;i++){\r
+ freq_count_table[i]=0;\r
+ }\r
+ for(int i=0;i<110;i++){\r
+ freq_table[i]=0;\r
+ }\r
+ final int raster_width=i_raster_size.w;\r
+ final int raster_height=i_raster_size.h;\r
+\r
+ final double cpara_0=cpara[0];\r
+ final double cpara_3=cpara[3];\r
+ final double cpara_6=cpara[6]; \r
+ \r
+ //10-20ピクセル目からタイミングパターンを検出\r
+ for(int i=0;i<FREQ_SAMPLE_NUM;i++){\r
+ //2行分のピクセルインデックスを計算\r
+ final double cy0=1+i_y1+i;\r
+ final double cpy0_12=cpara[1]*cy0+cpara[2];\r
+ final double cpy0_45=cpara[4]*cy0+cpara[5];\r
+ final double cpy0_7=cpara[7]*cy0+1.0;\r
+\r
+ int pt=0;\r
+ for(int i2=0;i2<FRQ_POINTS;i2++)\r
+ {\r
+ final double cx0=1+i2*FRQ_STEP+FRQ_EDGE; \r
+ final double d=(cpara_6*cx0)+cpy0_7;\r
+ final int x=(int)((cpara_0*cx0+cpy0_12)/d);\r
+ final int y=(int)((cpara_3*cx0+cpy0_45)/d);\r
+ if(x<0||y<0||x>=raster_width||y>=raster_height)\r
+ {\r
+ return -1;\r
+ }\r
+ ref_x[pt]=x;\r
+ ref_y[pt]=y;\r
+ pt++;\r
+ }\r
+ \r
+ //ピクセルを取得(入力画像を多様化するならここから先を調整すること)\r
+ i_reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+\r
+ //o_edge_indexを一時的に破壊して調査する\r
+ final int freq_t=getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index); \r
+ \r
+ //周期は3-10であること\r
+ if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+ continue;\r
+ }\r
+ //周期は等間隔であること\r
+ if(!checkFreqWidth(o_edge_index,freq_t)){\r
+ continue;\r
+ }\r
+ //検出カウンタを追加\r
+ freq_count_table[freq_t]++;\r
+ final int table_st=(freq_t-1)*freq_t;\r
+ for(int i2=0;i2<freq_t*2;i2++){\r
+ freq_table[table_st+i2]+=o_edge_index[i2];\r
+ }\r
+ }\r
+ return getMaxFreq(freq_count_table,freq_table,o_edge_index);\r
+ }\r
+ \r
+ public int getColFrequency(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,int i_x1,int i_th_h,int i_th_l,int[] o_edge_index)throws NyARException\r
+ {\r
+ final double[] cpara=this._cparam;\r
+// final INyARRgbPixelReader reader=this._raster.getRgbPixelReader();\r
+ final int[] ref_x=this._ref_x;\r
+ final int[] ref_y=this._ref_y;\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+ //0,2,4,6,8,10,12,14,16,18,20=(11*20)/2=110\r
+ //初期化\r
+ final int[] freq_count_table=this._freq_count_table;\r
+ for(int i=0;i<10;i++){\r
+ freq_count_table[i]=0;\r
+ }\r
+ final int[] freq_table=this._freq_table;\r
+ for(int i=0;i<110;i++){\r
+ freq_table[i]=0;\r
+ }\r
+ final int raster_width=i_raster_size.w;\r
+ final int raster_height=i_raster_size.h;\r
+ \r
+ \r
+ final double cpara7=cpara[7];\r
+ final double cpara4=cpara[4];\r
+ final double cpara1=cpara[1];\r
+ //基準点から4ピクセルを参照パターンとして抽出\r
+ for(int i=0;i<FREQ_SAMPLE_NUM;i++){\r
+\r
+ int cx0=1+i+i_x1;\r
+ final double cp6_0=cpara[6]*cx0;\r
+ final double cpx0_0=cpara[0]*cx0+cpara[2];\r
+ final double cpx3_0=cpara[3]*cx0+cpara[5];\r
+ \r
+ int pt=0;\r
+ for(int i2=0;i2<FRQ_POINTS;i2++)\r
+ {\r
+ int cy=1+i2*FRQ_STEP+FRQ_EDGE;\r
+ \r
+ final double d=cp6_0+cpara7*cy+1.0;\r
+ final int x=(int)((cpx0_0+cpara1*cy)/d);\r
+ final int y=(int)((cpx3_0+cpara4*cy)/d);\r
+ if(x<0||y<0||x>=raster_width||y>=raster_height)\r
+ {\r
+ return -1;\r
+ }\r
+ ref_x[pt]=x;\r
+ ref_y[pt]=y; \r
+ pt++;\r
+ } \r
+ \r
+ //ピクセルを取得(入力画像を多様化するならここを調整すること)\r
+ i_reader.getPixelSet(ref_x,ref_y,FRQ_POINTS,pixcel_temp);\r
+ \r
+ final int freq_t=getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);\r
+ //周期は3-10であること\r
+ if(freq_t<MIN_FREQ || freq_t>MAX_FREQ){\r
+ continue;\r
+ }\r
+ //周期は等間隔であること\r
+ if(!checkFreqWidth(o_edge_index,freq_t)){\r
+ continue;\r
+ }\r
+ //検出カウンタを追加\r
+ freq_count_table[freq_t]++;\r
+ final int table_st=(freq_t-1)*freq_t;\r
+ for(int i2=0;i2<freq_t*2;i2++){\r
+ freq_table[table_st+i2]+=o_edge_index[i2];\r
+ }\r
+ }\r
+ return getMaxFreq(freq_count_table,freq_table,o_edge_index); \r
+ }\r
+\r
+ /**\r
+ * デバックすんだらstaticにしておk\r
+ * @param i_pixcels\r
+ * @param i_th_h\r
+ * @param i_th_l\r
+ * @param o_edge_index\r
+ * @return\r
+ */\r
+ private static int getFreqInfo(int[] i_pixcels,int i_th_h,int i_th_l,int[] o_edge_index)\r
+ {\r
+ //トークンを解析して、周波数を計算\r
+ int i=0;\r
+ int frq_l2h=0;\r
+ int frq_h2l=0;\r
+ while(i<FRQ_POINTS){\r
+ //L->Hトークンを検出する\r
+ while(i<FRQ_POINTS){\r
+ final int index=i*3;\r
+ final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+ if(pix>i_th_h){\r
+ //トークン発見\r
+ o_edge_index[frq_l2h+frq_h2l]=i;\r
+ frq_l2h++;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ i++;\r
+ //L->Hトークンを検出する\r
+ while(i<FRQ_POINTS){\r
+ final int index=i*3;\r
+ final int pix=(i_pixcels[index+0]+i_pixcels[index+1]+i_pixcels[index+2])/3;\r
+ if(pix<=i_th_l){\r
+ //トークン発見\r
+ o_edge_index[frq_l2h+frq_h2l]=i;\r
+ frq_h2l++;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ i++;\r
+ }\r
+ return frq_l2h==frq_h2l?frq_l2h:-1; \r
+ }\r
+\r
+ private final static int THRESHOLD_EDGE=10;\r
+ private final static int THRESHOLD_STEP=2;\r
+ private final static int THRESHOLD_WIDTH=10;\r
+ private final static int THRESHOLD_PIXEL=THRESHOLD_WIDTH/THRESHOLD_STEP;\r
+ private final static int THRESHOLD_SAMPLE=THRESHOLD_PIXEL*THRESHOLD_PIXEL;\r
+ private final static int THRESHOLD_SAMPLE_LT=THRESHOLD_EDGE;\r
+ private final static int THRESHOLD_SAMPLE_RB=100-THRESHOLD_WIDTH-THRESHOLD_EDGE;\r
+ \r
+ public static class TThreshold{\r
+ public int th_h;\r
+ public int th_l;\r
+ public int th;\r
+ public int lt_x;\r
+ public int lt_y;\r
+ public int rb_x;\r
+ public int rb_y;\r
+ } \r
+\r
+ class THighAndLow{\r
+ public int h;\r
+ public int l;\r
+ }\r
+ /**\r
+ * ピクセル配列の上位、下位の4ピクセルのピクセル値平均を求めます。\r
+ * この関数は、(4/i_pixcel.length)の領域を占有するPtail法で双方向の閾値を求めることになります。\r
+ * @param i_pixcel\r
+ * @param i_initial\r
+ * @param i_out\r
+ */\r
+ private void getPtailHighAndLow(int[] i_pixcel,THighAndLow i_out)\r
+ {\r
+ int h3,h2,h1,h0,l3,l2,l1,l0;\r
+ h3=h2=h1=h0=l3=l2=l1=l0=i_pixcel[0];\r
+ \r
+ for(int i=i_pixcel.length-1;i>=1;i--){\r
+ final int pix=i_pixcel[i];\r
+ if(h0<pix){\r
+ if(h1<pix){\r
+ if(h2<pix){\r
+ if(h3<pix){\r
+ h0=h1;\r
+ h1=h2;\r
+ h2=h3;\r
+ h3=pix;\r
+ }else{\r
+ h0=h1;\r
+ h1=h2;\r
+ h2=pix;\r
+ }\r
+ }else{\r
+ h0=h1;\r
+ h1=pix;\r
+ }\r
+ }else{\r
+ h0=pix;\r
+ }\r
+ }\r
+ if(l0>pix){\r
+ if(l1>pix){\r
+ if(l2>pix){\r
+ if(l3>pix){\r
+ l0=l1;\r
+ l1=l2;\r
+ l2=l3;\r
+ l3=pix;\r
+ }else{\r
+ l0=l1;\r
+ l1=l2;\r
+ l2=pix;\r
+ }\r
+ }else{\r
+ l0=l1;\r
+ l1=pix;\r
+ }\r
+ }else{\r
+ l0=pix;\r
+ }\r
+ }\r
+ }\r
+ i_out.l=(l0+l1+l2+l3)/4;\r
+ i_out.h=(h0+h1+h2+h3)/4;\r
+ return;\r
+ }\r
+ private THighAndLow __detectThresholdValue_hl=new THighAndLow();\r
+ private NyARIntPoint2d __detectThresholdValue_tpt=new NyARIntPoint2d();\r
+ private int[] _th_pixels=new int[THRESHOLD_SAMPLE*4];\r
+ /**\r
+ * 指定した場所のピクセル値を調査して、閾値を計算して返します。\r
+ * @param i_reader\r
+ * @param i_x\r
+ * @param i_y\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public void detectThresholdValue(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,TThreshold o_threshold)throws NyARException\r
+ {\r
+ final int[] th_pixels=this._th_pixels;\r
+\r
+ //左上のピックアップ領域からピクセルを得る(00-24)\r
+ rectPixels(i_reader,i_raster_size,THRESHOLD_SAMPLE_LT,THRESHOLD_SAMPLE_LT,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,0,th_pixels);\r
+ \r
+ //左下のピックアップ領域からピクセルを得る(25-49)\r
+ rectPixels(i_reader,i_raster_size,THRESHOLD_SAMPLE_LT,THRESHOLD_SAMPLE_RB,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE,th_pixels);\r
+ \r
+ //右上のピックアップ領域からピクセルを得る(50-74)\r
+ rectPixels(i_reader,i_raster_size,THRESHOLD_SAMPLE_RB,THRESHOLD_SAMPLE_LT,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE*2,th_pixels);\r
+\r
+ //右下のピックアップ領域からピクセルを得る(75-99)\r
+ rectPixels(i_reader,i_raster_size,THRESHOLD_SAMPLE_RB,THRESHOLD_SAMPLE_RB,THRESHOLD_STEP,THRESHOLD_STEP,THRESHOLD_PIXEL,THRESHOLD_PIXEL,THRESHOLD_SAMPLE*3,th_pixels);\r
+\r
+ final THighAndLow hl=this.__detectThresholdValue_hl;\r
+ //Ptailで求めたピクセル平均\r
+ getPtailHighAndLow(th_pixels,hl);\r
+\r
+\r
+ \r
+ //閾値中心\r
+ int th=(hl.h+hl.l)/2;\r
+ //ヒステリシス(差分の20%)\r
+ int th_sub=(hl.h-hl.l)/5;\r
+ \r
+ o_threshold.th=th;\r
+ o_threshold.th_h=th+th_sub;//ヒステリシス付き閾値\r
+ o_threshold.th_l=th-th_sub;//ヒステリシス付き閾値\r
+\r
+ //エッジを計算(明点重心)\r
+ int lt_x,lt_y,lb_x,lb_y,rt_x,rt_y,rb_x,rb_y;\r
+ final NyARIntPoint2d tpt=this.__detectThresholdValue_tpt;\r
+ //LT\r
+ if(getHighPixelCenter(0,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+ lt_x=tpt.x*THRESHOLD_STEP;\r
+ lt_y=tpt.y*THRESHOLD_STEP;\r
+ }else{\r
+ lt_x=11;\r
+ lt_y=11;\r
+ }\r
+ //LB\r
+ if(getHighPixelCenter(THRESHOLD_SAMPLE*1,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+ lb_x=tpt.x*THRESHOLD_STEP;\r
+ lb_y=tpt.y*THRESHOLD_STEP;\r
+ }else{\r
+ lb_x=11;\r
+ lb_y=-1;\r
+ }\r
+ //RT\r
+ if(getHighPixelCenter(THRESHOLD_SAMPLE*2,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+ rt_x=tpt.x*THRESHOLD_STEP;\r
+ rt_y=tpt.y*THRESHOLD_STEP;\r
+ }else{\r
+ rt_x=-1;\r
+ rt_y=11;\r
+ }\r
+ //RB\r
+ if(getHighPixelCenter(THRESHOLD_SAMPLE*3,th_pixels,THRESHOLD_PIXEL,THRESHOLD_PIXEL,th,tpt)){\r
+ rb_x=tpt.x*THRESHOLD_STEP;\r
+ rb_y=tpt.y*THRESHOLD_STEP;\r
+ }else{\r
+ rb_x=-1;\r
+ rb_y=-1;\r
+ }\r
+ //トラッキング開始位置の決定\r
+ o_threshold.lt_x=(lt_x+lb_x)/2+THRESHOLD_SAMPLE_LT-1;\r
+ o_threshold.rb_x=(rt_x+rb_x)/2+THRESHOLD_SAMPLE_RB+1;\r
+ o_threshold.lt_y=(lt_y+rt_y)/2+THRESHOLD_SAMPLE_LT-1;\r
+ o_threshold.rb_y=(lb_y+rb_y)/2+THRESHOLD_SAMPLE_RB+1;\r
+ return;\r
+ }\r
+\r
+ private boolean getHighPixelCenter(int i_st,final int[] i_pixels,int i_width,int i_height,int i_th,NyARIntPoint2d o_point)\r
+ {\r
+ int rp=i_st;\r
+ int pos_x=0;\r
+ int pos_y=0;\r
+ int number_of_pos=0;\r
+ for(int i=0;i<i_height;i++){\r
+ for(int i2=0;i2<i_width;i2++){\r
+ if(i_pixels[rp++]>i_th){\r
+ pos_x+=i2;\r
+ pos_y+=i;\r
+ number_of_pos++;\r
+ }\r
+ }\r
+ }\r
+ if(number_of_pos>0){\r
+ pos_x/=number_of_pos;\r
+ pos_y/=number_of_pos;\r
+ }else{\r
+ return false;\r
+ }\r
+ o_point.x=pos_x;\r
+ o_point.y=pos_y;\r
+ return true;\r
+ }\r
+ private int[] __detectDataBitsIndex_freq_index1=new int[FRQ_POINTS];\r
+ private int[] __detectDataBitsIndex_freq_index2=new int[FRQ_POINTS];\r
+ private int detectDataBitsIndex(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,PerspectivePixelReader.TThreshold i_th,double[] o_index_row,double[] o_index_col) throws NyARException\r
+ {\r
+ //周波数を測定\r
+ final int[] freq_index1=this.__detectDataBitsIndex_freq_index1;\r
+ final int[] freq_index2=this.__detectDataBitsIndex_freq_index2;\r
+ \r
+ int frq_t=getRowFrequency(i_reader,i_raster_size,i_th.lt_y,i_th.th_h,i_th.th_l,freq_index1);\r
+ int frq_b=getRowFrequency(i_reader,i_raster_size,i_th.rb_y,i_th.th_h,i_th.th_l,freq_index2);\r
+ //周波数はまとも?\r
+ if((frq_t<0 && frq_b<0) || frq_t==frq_b){\r
+ return -1;\r
+ }\r
+ //タイミングパターンからインデクスを作成\r
+ int freq_h,freq_v;\r
+ int[] index;\r
+ if(frq_t>frq_b){\r
+ freq_h=frq_t;\r
+ index=freq_index1;\r
+ }else{\r
+ freq_h=frq_b;\r
+ index=freq_index2;\r
+ }\r
+ for(int i=0;i<freq_h+freq_h-1;i++){\r
+ o_index_row[i*2]=((index[i+1]-index[i])*2/5+index[i])+FRQ_EDGE;\r
+ o_index_row[i*2+1]=((index[i+1]-index[i])*3/5+index[i])+FRQ_EDGE;\r
+ } \r
+ \r
+ \r
+ final int frq_l=getColFrequency(i_reader,i_raster_size,i_th.lt_x,i_th.th_h,i_th.th_l,freq_index1);\r
+ final int frq_r=getColFrequency(i_reader,i_raster_size,i_th.rb_x,i_th.th_h,i_th.th_l,freq_index2);\r
+ //周波数はまとも?\r
+ if((frq_l<0 && frq_r<0) || frq_l==frq_r){\r
+ return -1;\r
+ }\r
+ //タイミングパターンからインデクスを作成\r
+ if(frq_l>frq_r){\r
+ freq_v=frq_l;\r
+ index=freq_index1;\r
+ }else{\r
+ freq_v=frq_r;\r
+ index=freq_index2;\r
+ }\r
+ //同じ周期?\r
+ if(freq_v!=freq_h){\r
+ return -1;\r
+ }\r
+ \r
+ for(int i=0;i<freq_v+freq_v-1;i++){\r
+ final int w=index[i];\r
+ final int w2=index[i+1]-w;\r
+ o_index_col[i*2]=((w2)*2/5+w)+FRQ_EDGE;\r
+ o_index_col[i*2+1]=((w2)*3/5+w)+FRQ_EDGE;\r
+ } \r
+ //Lv4以上は無理\r
+ if(freq_v>MAX_FREQ){\r
+ return -1;\r
+ }\r
+ return freq_v;\r
+ \r
+ }\r
+ private double[] __readDataBits_index_bit_x=new double[MAX_DATA_BITS*2];\r
+ private double[] __readDataBits_index_bit_y=new double[MAX_DATA_BITS*2];\r
+ \r
+ public boolean readDataBits(INyARRgbPixelReader i_reader,NyARIntSize i_raster_size,PerspectivePixelReader.TThreshold i_th,MarkerPattEncoder o_bitbuffer)throws NyARException\r
+ {\r
+ final double[] index_x=this.__readDataBits_index_bit_x;\r
+ final double[] index_y=this.__readDataBits_index_bit_y;\r
+ \r
+\r
+ //読み出し位置を取得\r
+ final int size=detectDataBitsIndex(i_reader,i_raster_size,i_th,index_x,index_y);\r
+ final int resolution=size+size-1;\r
+ if(size<0){\r
+ return false;\r
+ }\r
+ if(!o_bitbuffer.initEncoder(size-1)){\r
+ return false;\r
+ } \r
+ \r
+ final double[] cpara=this._cparam;\r
+ final int[] ref_x=this._ref_x;\r
+ final int[] ref_y=this._ref_y;\r
+ final int[] pixcel_temp=this._pixcel_temp;\r
+ \r
+ final double cpara_0=cpara[0];\r
+ final double cpara_1=cpara[1];\r
+ final double cpara_3=cpara[3];\r
+ final double cpara_6=cpara[6];\r
+ \r
+ \r
+ final int th=i_th.th;\r
+ int p=0;\r
+ for(int i=0;i<resolution;i++){\r
+ //1列分のピクセルのインデックス値を計算する。\r
+ double cy0=1+index_y[i*2+0];\r
+ double cy1=1+index_y[i*2+1]; \r
+ double cpy0_12=cpara_1*cy0+cpara[2];\r
+ double cpy0_45=cpara[4]*cy0+cpara[5];\r
+ double cpy0_7=cpara[7]*cy0+1.0;\r
+ double cpy1_12=cpara_1*cy1+cpara[2];\r
+ double cpy1_45=cpara[4]*cy1+cpara[5];\r
+ double cpy1_7=cpara[7]*cy1+1.0;\r
+ \r
+ int pt=0;\r
+ for(int i2=0;i2<resolution;i2++)\r
+ { \r
+\r
+ double d;\r
+ double cx0=1+index_x[i2*2+0];\r
+ double cx1=1+index_x[i2*2+1];\r
+\r
+ double cp6_0=cpara_6*cx0;\r
+ double cpx0_0=cpara_0*cx0;\r
+ double cpx3_0=cpara_3*cx0;\r
+\r
+ double cp6_1=cpara_6*cx1;\r
+ double cpx0_1=cpara_0*cx1;\r
+ double cpx3_1=cpara_3*cx1;\r
+ \r
+ d=cp6_0+cpy0_7;\r
+ ref_x[pt]=(int)((cpx0_0+cpy0_12)/d);\r
+ ref_y[pt]=(int)((cpx3_0+cpy0_45)/d);\r
+ pt++;\r
+\r
+ d=cp6_0+cpy1_7;\r
+ ref_x[pt]=(int)((cpx0_0+cpy1_12)/d);\r
+ ref_y[pt]=(int)((cpx3_0+cpy1_45)/d);\r
+ pt++;\r
+\r
+ d=cp6_1+cpy0_7;\r
+ ref_x[pt]=(int)((cpx0_1+cpy0_12)/d);\r
+ ref_y[pt]=(int)((cpx3_1+cpy0_45)/d);\r
+ pt++;\r
+\r
+ d=cp6_1+cpy1_7;\r
+ ref_x[pt]=(int)((cpx0_1+cpy1_12)/d);\r
+ ref_y[pt]=(int)((cpx3_1+cpy1_45)/d);\r
+ pt++;\r
+ }\r
+ //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)\r
+ i_reader.getPixelSet(ref_x,ref_y,resolution*4,pixcel_temp);\r
+ //グレースケールにしながら、line→mapへの転写\r
+ for(int i2=0;i2<resolution;i2++){\r
+ int index=i2*3*4;\r
+ int pixel=( pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2]+\r
+ pixcel_temp[index+3]+pixcel_temp[index+4]+pixcel_temp[index+5]+\r
+ pixcel_temp[index+6]+pixcel_temp[index+7]+pixcel_temp[index+8]+\r
+ pixcel_temp[index+9]+pixcel_temp[index+10]+pixcel_temp[index+11])/(4*3);\r
+ //暗点を1、明点を0で表現します。\r
+ o_bitbuffer.setBitByBitIndex(p,pixel>th?0:1);\r
+ p++;\r
+ }\r
+ }\r
+/* \r
+ for(int i=0;i<225*4;i++){\r
+ this.vertex_x[i]=0;\r
+ this.vertex_y[i]=0;\r
+ }\r
+ for(int i=0;i<(resolution)*2;i++){\r
+ for(int i2=0;i2<(resolution)*2;i2++){\r
+ this.vertex_x[i*(resolution)*2+i2]=(int)index_x[i2];\r
+ this.vertex_y[i*(resolution)*2+i2]=(int)index_y[i];\r
+ \r
+ }\r
+ }\r
+*/ return true;\r
+ }\r
+ public boolean setSquare(NyARIntPoint2d[] i_vertex) throws NyARException\r
+ {\r
+ if (!this._param_gen.getParam(i_vertex,this._cparam)) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+}\r
+class MarkerPattDecoder\r
+{\r
+ public void decode(int model,int domain,int mask)\r
+ {\r
+ \r
+ }\r
+}\r
+/**\r
+ * マーカパターンのエンコーダです。\r
+ *\r
+ */\r
+class MarkerPattEncoder\r
+{\r
+ private final static int[] _bit_table_3={\r
+ 25, 26, 27, 28, 29, 30, 31,\r
+ 48, 9, 10, 11, 12, 13, 32,\r
+ 47, 24, 1, 2, 3, 14, 33,\r
+ 46, 23, 8, 0, 4, 15, 34,\r
+ 45, 22, 7, 6, 5, 16, 35,\r
+ 44, 21, 20, 19, 18, 17, 36,\r
+ 43, 42, 41, 40, 39, 38, 37\r
+ }; \r
+ private final static int[] _bit_table_2={\r
+ 9, 10, 11, 12, 13,\r
+ 24, 1, 2, 3, 14,\r
+ 23, 8, 0, 4, 15,\r
+ 22, 7, 6, 5, 16,\r
+ 21, 20, 19, 18, 17};\r
+ private final static int[][] _bit_tables={\r
+ _bit_table_2,_bit_table_3,null,null,null,null,null,\r
+ };\r
+ /**\r
+ * RECT(0):[0]=(0)\r
+ * RECT(1):[1]=(1-8)\r
+ * RECT(2):[2]=(9-16),[3]=(17-24)\r
+ * RECT(3):[4]=(25-32),[5]=(33-40),[6]=(41-48)\r
+ */\r
+ int[] _bit_table;\r
+ int[] _bits=new int[16];\r
+ int[] _work=new int[16];\r
+ int _model;\r
+ public void setBitByBitIndex(int i_index_no,int i_value)\r
+ {\r
+ assert i_value==0 || i_value==1;\r
+ final int bit_no=this._bit_table[i_index_no];\r
+ if(bit_no==0){\r
+ this._bits[0]=i_value;\r
+ }else{\r
+ int bidx=(bit_no-1)/8+1;\r
+ int sidx=(bit_no-1)%8;\r
+ this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+ }\r
+ return;\r
+ }\r
+ \r
+ public void setBit(int i_bit_no,int i_value)\r
+ {\r
+ assert i_value==0 || i_value==1;\r
+ if(i_bit_no==0){\r
+ this._bits[0]=i_value;\r
+ }else{\r
+ int bidx=(i_bit_no-1)/8+1;\r
+ int sidx=(i_bit_no-1)%8;\r
+ this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);\r
+ }\r
+ return;\r
+ }\r
+ public int getBit(int i_bit_no)\r
+ {\r
+ if(i_bit_no==0){\r
+ return this._bits[0];\r
+ }else{\r
+ int bidx=(i_bit_no-1)/8+1;\r
+ int sidx=(i_bit_no-1)%8;\r
+ return (this._bits[bidx]>>(sidx))&(0x01);\r
+ }\r
+ }\r
+ public int getModel()\r
+ {\r
+ return this._model;\r
+ }\r
+ private static int getControlValue(int i_model,int[] i_data)\r
+ {\r
+ int v;\r
+ switch(i_model){\r
+ case 2:\r
+ v=(i_data[2] & 0x0e)>>1;\r
+ return v>=5?v-1:v;\r
+ case 3:\r
+ v=(i_data[4] & 0x3e)>>1;\r
+ return v>=21?v-1:v;\r
+ case 4:\r
+ case 5:\r
+ case 6:\r
+ case 7:\r
+ default:\r
+ break;\r
+ }\r
+ return -1;\r
+ }\r
+ public static int getCheckValue(int i_model,int[] i_data)\r
+ {\r
+ int v;\r
+ switch(i_model){\r
+ case 2:\r
+ v=(i_data[2] & 0xe0)>>5;\r
+ return v>5?v-1:v;\r
+ case 3:\r
+ v=((i_data[4] & 0x80)>>7) |((i_data[5] & 0x0f)<<1);\r
+ return v>21?v-1:v;\r
+ case 4:\r
+ case 5:\r
+ case 6:\r
+ case 7:\r
+ default:\r
+ break;\r
+ }\r
+ return -1;\r
+ }\r
+ public boolean initEncoder(int i_model)\r
+ {\r
+ if(i_model>3 || i_model<2){\r
+ //Lv4以降に対応する時は、この制限を変える。\r
+ return false;\r
+ }\r
+ this._bit_table=_bit_tables[i_model-2];\r
+ this._model=i_model;\r
+ return true;\r
+ }\r
+ private int getDirection()\r
+ {\r
+ int l,t,r,b;\r
+ int timing_pat;\r
+ switch(this._model){\r
+ case 2:\r
+ //トラッキングセルを得る\r
+ t=this._bits[2] & 0x1f;\r
+ r=((this._bits[2] & 0xf0)>>4)|((this._bits[3]&0x01)<<4);\r
+ b=this._bits[3] & 0x1f;\r
+ l=((this._bits[3] & 0xf0)>>4)|((this._bits[2]&0x01)<<4);\r
+ timing_pat=0x0a;\r
+ break;\r
+ case 3:\r
+ t=this._bits[4] & 0x7f;\r
+ r=((this._bits[4] & 0xc0)>>6)|((this._bits[5] & 0x1f)<<2);\r
+ b=((this._bits[5] & 0xf0)>>4)|((this._bits[6] & 0x07)<<4);\r
+ l=((this._bits[6] & 0xfc)>>2)|((this._bits[4] & 0x01)<<6);\r
+ timing_pat=0x2a;\r
+ break;\r
+ default:\r
+ return -3;\r
+ }\r
+ //タイミングパターンの比較\r
+ if(t==timing_pat){\r
+ if(r==timing_pat){\r
+ return (b!=timing_pat && l!=timing_pat)?2:-2;\r
+ }else if(l==timing_pat){\r
+ return (b!=timing_pat && r!=timing_pat)?3:-2;\r
+ }\r
+ }else if(b==timing_pat){\r
+ if(r==timing_pat){\r
+ return (t!=timing_pat && l!=timing_pat)?1:-2;\r
+ }else if(l==timing_pat){\r
+ return (t!=timing_pat && r!=timing_pat)?0:-2;\r
+ }\r
+ }\r
+ return -1;\r
+ }\r
+ /**\r
+ * 格納しているマーカパターンをエンコードして、マーカデータを返します。\r
+ * @param o_out\r
+ * @return\r
+ * 成功すればマーカの方位を返却します。失敗すると-1を返します。\r
+ */\r
+\r
+ public int encode(NyIdMarkerPattern o_out)\r
+ {\r
+ final int d=getDirection();\r
+ if(d<0){\r
+ return -1;\r
+ }\r
+ //回転ビットの取得\r
+ getRotatedBits(d,o_out.data);\r
+ final int model=this._model;\r
+ //周辺ビットの取得\r
+ o_out.model=model;\r
+ int control_bits=getControlValue(model,o_out.data);\r
+ o_out.check=getCheckValue(model,o_out.data);\r
+ o_out.ctrl_mask=control_bits%5;\r
+ o_out.ctrl_domain=control_bits/5;\r
+ if(o_out.ctrl_domain!=0 || o_out.ctrl_mask!=0){\r
+ return -1;\r
+ }\r
+ //マスク解除処理を実装すること\r
+ return d;\r
+ }\r
+ private void getRotatedBits(int i_direction,int[] o_out)\r
+ {\r
+ int sl=i_direction*2;\r
+ int sr=8-sl;\r
+\r
+ int w1;\r
+ o_out[0]=this._bits[0];\r
+ //RECT1\r
+ w1=this._bits[1];\r
+ o_out[1]=((w1<<sl)|(w1>>sr))& 0xff;\r
+ \r
+ //RECT2\r
+ sl=i_direction*4;\r
+ sr=16-sl;\r
+ w1=this._bits[2]|(this._bits[3]<<8);\r
+ w1=(w1<<sl)|(w1>>sr);\r
+ o_out[2]=w1 & 0xff;\r
+ o_out[3]=(w1>>8) & 0xff;\r
+\r
+ if(this._model<2){\r
+ return;\r
+ }\r
+\r
+ //RECT3\r
+ sl=i_direction*6;\r
+ sr=24-sl; \r
+ w1=this._bits[4]|(this._bits[5]<<8)|(this._bits[6]<<16);\r
+ w1=(w1<<sl)|(w1>>sr);\r
+ o_out[4]=w1 & 0xff;\r
+ o_out[5]=(w1>>8) & 0xff;\r
+ o_out[6]=(w1>>16) & 0xff;\r
+ \r
+ if(this._model<3){\r
+ return;\r
+ }\r
+ //RECT4(Lv4以降はここの制限を変える)\r
+// shiftLeft(this._bits,7,3,i_direction*8);\r
+// if(this._model<4){\r
+// return;\r
+// }\r
+ return;\r
+ }\r
+ public void shiftLeft(int[] i_pack,int i_start,int i_length,int i_ls)\r
+ {\r
+ int[] work=this._work;\r
+ //端数シフト\r
+ final int mod_shift=i_ls%8;\r
+ for(int i=i_length-1;i>=1;i--){\r
+ work[i]=(i_pack[i+i_start]<<mod_shift)|(0xff&(i_pack[i+i_start-1]>>(8-mod_shift)));\r
+ }\r
+ work[0]=(i_pack[i_start]<<mod_shift)|(0xff&(i_pack[i_start+i_length-1]>>(8-mod_shift)));\r
+ //バイトシフト\r
+ final int byte_shift=(i_ls/8)%i_length;\r
+ for(int i=i_length-1;i>=0;i--){\r
+ i_pack[(byte_shift+i)%i_length+i_start]=0xff & work[i];\r
+ }\r
+ return;\r
+ } \r
+}\r
+/**\r
+ * ラスタ画像の任意矩形から、NyARIdMarkerDataを抽出します。\r
+ *\r
+ */\r
+public class NyIdMarkerPickup\r
+{\r
+ private PerspectivePixelReader _perspective_reader;\r
+ private final PerspectivePixelReader.TThreshold __pickFromRaster_th=new PerspectivePixelReader.TThreshold();\r
+ private final MarkerPattEncoder __pickFromRaster_encoder=new MarkerPattEncoder();\r
+\r
+\r
+ public NyIdMarkerPickup()\r
+ {\r
+ this._perspective_reader=new PerspectivePixelReader();\r
+ return;\r
+ }\r
+ /**\r
+ * i_imageから、idマーカを読みだします。\r
+ * o_dataにはマーカデータ、o_paramにはまーかのパラメータを返却します。\r
+ * @param image\r
+ * @param i_square\r
+ * @param o_data\r
+ * @param o_param\r
+ * @return\r
+ * @throws NyARException\r
+ */\r
+ public boolean pickFromRaster(INyARRgbRaster image, NyARIntPoint2d[] i_vertex,NyIdMarkerPattern o_data,NyIdMarkerParam o_param)throws NyARException\r
+ {\r
+ \r
+ //遠近法のパラメータを計算\r
+ if(!this._perspective_reader.setSourceSquare(i_vertex)){\r
+ return false;\r
+ };\r
+ \r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ NyARIntSize raster_size=image.getSize();\r
+ \r
+\r
+\r
+ final PerspectivePixelReader.TThreshold th=this.__pickFromRaster_th;\r
+ final MarkerPattEncoder encoder=this.__pickFromRaster_encoder;\r
+ //マーカパラメータを取得\r
+ this._perspective_reader.detectThresholdValue(reader,raster_size,th);\r
+\r
+ if(!this._perspective_reader.readDataBits(reader,raster_size,th, encoder)){\r
+ return false;\r
+ }\r
+ final int d=encoder.encode(o_data);\r
+ if(d<0){\r
+ return false;\r
+ }\r
+ o_param.direction=d;\r
+ o_param.threshold=th.th;\r
+ \r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+/**\r
+ * \r
+ * [[Strage class]]\r
+ *\r
+ */\r
+public interface INyIdMarkerData\r
+{\r
+ /**\r
+ * i_targetのマーカデータと自身のデータが等しいかを返します。\r
+ * @param i_target\r
+ * 比較するマーカオブジェクト\r
+ * @return\r
+ * 等しいかの真偽値\r
+ */\r
+ public boolean isEqual(INyIdMarkerData i_target);\r
+ /**\r
+ * i_sourceからマーカデータをコピーします。\r
+ * @param i_source\r
+ */\r
+ public void copyFrom(INyIdMarkerData i_source);\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+import jp.nyatla.nyartoolkit.nyidmarker.NyIdMarkerPattern;\r
+\r
+\r
+public interface INyIdMarkerDataEncoder\r
+{\r
+ public boolean encode(NyIdMarkerPattern i_data,INyIdMarkerData o_dest);\r
+ public INyIdMarkerData createDataInstance();\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+import jp.nyatla.nyartoolkit.nyidmarker.*;\r
+\r
+\r
+public class NyIdMarkerDataEncoder_RawBit implements INyIdMarkerDataEncoder\r
+{ \r
+ private final static int _DOMAIN_ID=0;\r
+ private final static int[] _mod_data={7,31,127,511,2047,4095};\r
+ public boolean encode(NyIdMarkerPattern i_data,INyIdMarkerData o_dest)\r
+ {\r
+ final NyIdMarkerData_RawBit dest=(NyIdMarkerData_RawBit)o_dest;\r
+ if(i_data.ctrl_domain!=_DOMAIN_ID){\r
+ return false;\r
+ }\r
+ //パケット数計算\r
+ final int resolution_len=(i_data.model+1);\r
+ final int packet_length=(resolution_len*resolution_len)/8+1;\r
+ int sum=0;\r
+ for(int i=0;i<packet_length;i++){\r
+ dest.packet[i]=i_data.data[i];\r
+ sum+=i_data.data[i];\r
+ }\r
+ //チェックドット値計算\r
+ sum=sum%_mod_data[i_data.model-2];\r
+ //チェックドット比較\r
+ if(i_data.check!=sum){\r
+ return false;\r
+ }\r
+ dest.length=packet_length;\r
+ return true;\r
+ }\r
+ public INyIdMarkerData createDataInstance()\r
+ {\r
+ return new NyIdMarkerData_RawBit();\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit(Extension)\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.nyidmarker.data;\r
+\r
+/**\r
+ * [[Strage class]]\r
+ *\r
+ */\r
+public class NyIdMarkerData_RawBit implements INyIdMarkerData\r
+{\r
+ public final int[] packet=new int[22];\r
+ public int length;\r
+ public boolean isEqual(INyIdMarkerData i_target)\r
+ {\r
+ NyIdMarkerData_RawBit s=(NyIdMarkerData_RawBit)i_target;\r
+ if(s.length!=this.length){\r
+ return false;\r
+ }\r
+ for(int i=s.length-1;i>=0;i--){\r
+ if(s.packet[i]!=this.packet[i]){\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ public void copyFrom(INyIdMarkerData i_source)\r
+ {\r
+ final NyIdMarkerData_RawBit s=(NyIdMarkerData_RawBit)i_source;\r
+ System.arraycopy(s.packet,0,this.packet,0,s.length);\r
+ this.length=s.length;\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * Capture Test NyARToolkitCSサンプルプログラム\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.processor;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.analyzer.raster.threshold.*;\r
+import jp.nyatla.nyartoolkit.core.match.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilter_ARToolkitThreshold;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+\r
+/**\r
+ * このクラスは、同時に1個のマーカを処理することのできる、アプリケーションプロセッサです。\r
+ * マーカの出現・移動・消滅を、イベントで通知することができます。\r
+ * クラスには複数のマーカを登録できます。一つのマーカが見つかると、プロセッサは継続して同じマーカを\r
+ * 1つだけ認識し続け、見失うまでの間は他のマーカを認識しません。\r
+ * \r
+ * イベントは、 OnEnter→OnUpdate[n]→OnLeaveの順で発生します。\r
+ * マーカが見つかるとまずOnEnterが1度発生して、何番のマーカが発見されたかがわかります。\r
+ * 次にOnUpdateにより、現在の変換行列が連続して渡されます。最後にマーカを見失うと、OnLeave\r
+ * イベントが発生します。\r
+ * \r
+ */\r
+public abstract class SingleARMarkerProcesser\r
+{\r
+ /**\r
+ * detectMarkerのコールバック関数\r
+ */\r
+ private class DetectSquareCB implements INyARSquareContourDetector.DetectMarkerCallback\r
+ {\r
+ //公開プロパティ\r
+ public final NyARSquare square=new NyARSquare();\r
+ public double confidence=0.0;\r
+ public int code_index=-1; \r
+ public double cf_threshold_new = 0.30;\r
+ public double cf_threshold_exist = 0.15;\r
+ \r
+ //参照\r
+ private INyARRgbRaster _ref_raster;\r
+ //所有インスタンス\r
+ private INyARColorPatt _inst_patt;\r
+ private NyARMatchPattDeviationColorData _deviation_data;\r
+ private NyARMatchPatt_Color_WITHOUT_PCA[] _match_patt;\r
+ private final NyARMatchPattResult __detectMarkerLite_mr=new NyARMatchPattResult();\r
+ private Coord2Linear _coordline;\r
+ \r
+ public DetectSquareCB(NyARParam i_param)\r
+ {\r
+ this._match_patt=null;\r
+ this._coordline=new Coord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+ return;\r
+ }\r
+ public void setNyARCodeTable(NyARCode[] i_ref_code,int i_code_resolution)\r
+ {\r
+ /*unmanagedで実装するときは、ここでリソース解放をすること。*/\r
+ this._deviation_data=new NyARMatchPattDeviationColorData(i_code_resolution,i_code_resolution);\r
+ this._inst_patt=new NyARColorPatt_Perspective_O2(i_code_resolution,i_code_resolution,4,25);\r
+ this._match_patt = new NyARMatchPatt_Color_WITHOUT_PCA[i_ref_code.length];\r
+ for(int i=0;i<i_ref_code.length;i++){\r
+ this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]);\r
+ }\r
+ }\r
+ private NyARIntPoint2d[] __tmp_vertex=NyARIntPoint2d.createArray(4);\r
+ /**\r
+ * Initialize call back handler.\r
+ */\r
+ public void init(INyARRgbRaster i_raster)\r
+ {\r
+ this._ref_raster=i_raster;\r
+ this.code_index=-1;\r
+ this.confidence=Double.MIN_NORMAL;\r
+ }\r
+\r
+ /**\r
+ * 矩形が見付かるたびに呼び出されます。\r
+ * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+ */\r
+ public void onSquareDetect(INyARSquareContourDetector i_sender,int[] i_coordx,int[] i_coordy,int i_coor_num,int[] i_vertex_index) throws NyARException\r
+ {\r
+ if (this._match_patt==null) {\r
+ return;\r
+ }\r
+ //輪郭座標から頂点リストに変換\r
+ NyARIntPoint2d[] vertex=this.__tmp_vertex;\r
+ vertex[0].x=i_coordx[i_vertex_index[0]];\r
+ vertex[0].y=i_coordy[i_vertex_index[0]];\r
+ vertex[1].x=i_coordx[i_vertex_index[1]];\r
+ vertex[1].y=i_coordy[i_vertex_index[1]];\r
+ vertex[2].x=i_coordx[i_vertex_index[2]];\r
+ vertex[2].y=i_coordy[i_vertex_index[2]];\r
+ vertex[3].x=i_coordx[i_vertex_index[3]];\r
+ vertex[3].y=i_coordy[i_vertex_index[3]];\r
+ \r
+ //画像を取得\r
+ if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){\r
+ return;//取得失敗\r
+ }\r
+ //取得パターンをカラー差分データに変換して評価する。\r
+ this._deviation_data.setRaster(this._inst_patt);\r
+\r
+ \r
+ //code_index,dir,c1にデータを得る。\r
+ final NyARMatchPattResult mr=this.__detectMarkerLite_mr;\r
+ int lcode_index = 0;\r
+ int dir = 0;\r
+ double c1 = 0;\r
+ for (int i = 0; i < this._match_patt.length; i++) {\r
+ this._match_patt[i].evaluate(this._deviation_data,mr);\r
+ double c2 = mr.confidence;\r
+ if (c1 < c2) {\r
+ lcode_index = i;\r
+ c1 = c2;\r
+ dir = mr.direction;\r
+ }\r
+ }\r
+ \r
+ //認識処理\r
+ if (this.code_index == -1) { // マーカ未認識\r
+ //現在は未認識\r
+ if (c1 < this.cf_threshold_new) {\r
+ return;\r
+ }\r
+ if (this.confidence > c1) {\r
+ // 一致度が低い。\r
+ return;\r
+ }\r
+ //認識しているマーカIDを保存\r
+ this.code_index=lcode_index;\r
+ }else{\r
+ //現在はマーカ認識中 \r
+ // 現在のマーカを認識したか?\r
+ if (lcode_index != this.code_index) {\r
+ // 認識中のマーカではないので無視\r
+ return;\r
+ }\r
+ //認識中の閾値より大きいか?\r
+ if (c1 < this.cf_threshold_exist) {\r
+ return;\r
+ }\r
+ //現在の候補よりも一致度は大きいか?\r
+ if (this.confidence>c1) {\r
+ return;\r
+ }\r
+ }\r
+ //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。\r
+ //ココから先はこの条件でしか実行されない。\r
+ \r
+ //一致率の高い矩形があれば、方位を考慮して頂点情報を作成\r
+ this.confidence=c1;\r
+ NyARSquare sq=this.square;\r
+ //directionを考慮して、squareを更新する。\r
+ for(int i=0;i<4;i++){\r
+ int idx=(i+4 - dir) % 4;\r
+ sq.imvertex[i].x=vertex[idx].x;\r
+ sq.imvertex[i].y=vertex[idx].y;\r
+ this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);\r
+ }\r
+ for (int i = 0; i < 4; i++) {\r
+ //直線同士の交点計算\r
+ if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+ throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+ }\r
+ }\r
+ }\r
+ } \r
+ /**オーナーが自由に使えるタグ変数です。\r
+ */\r
+ public Object tag;\r
+\r
+ private int _lost_delay_count = 0;\r
+\r
+ private int _lost_delay = 5;\r
+\r
+ private INyARSquareContourDetector _square_detect;\r
+\r
+ protected INyARTransMat _transmat;\r
+\r
+ private double _marker_width;\r
+ private int _threshold = 110;\r
+ // [AR]検出結果の保存用\r
+ private NyARBinRaster _bin_raster;\r
+\r
+ private NyARRasterFilter_ARToolkitThreshold _tobin_filter;\r
+\r
+ protected int _current_arcode_index = -1;\r
+\r
+ private NyARRasterThresholdAnalyzer_SlidePTile _threshold_detect;\r
+ \r
+ protected SingleARMarkerProcesser()\r
+ {\r
+ return;\r
+ }\r
+\r
+ private boolean _initialized=false;\r
+\r
+ protected void initInstance(NyARParam i_param,int i_raster_type) throws NyARException\r
+ {\r
+ //初期化済?\r
+ assert this._initialized==false;\r
+ \r
+ NyARIntSize scr_size = i_param.getScreenSize();\r
+ // 解析オブジェクトを作る\r
+ this._square_detect = new NyARSquareContourDetector_Rle(i_param.getDistortionFactor(), scr_size);\r
+ this._transmat = new NyARTransMat(i_param);\r
+ this._tobin_filter=new NyARRasterFilter_ARToolkitThreshold(110,i_raster_type);\r
+\r
+ // 2値画像バッファを作る\r
+ this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h);\r
+ this._threshold_detect=new NyARRasterThresholdAnalyzer_SlidePTile(15,i_raster_type,4);\r
+ this._initialized=true;\r
+ //コールバックハンドラ\r
+ this._detectmarker_cb=new DetectSquareCB(i_param);\r
+ \r
+ return;\r
+ }\r
+\r
+ /*自動・手動の設定が出来ないので、コメントアウト\r
+ public void setThreshold(int i_threshold)\r
+ {\r
+ this._threshold = i_threshold;\r
+ return;\r
+ }*/\r
+\r
+ /**検出するマーカコードの配列を指定します。 検出状態でこの関数を実行すると、\r
+ * オブジェクト状態に強制リセットがかかります。\r
+ */\r
+ public void setARCodeTable(NyARCode[] i_ref_code_table, int i_code_resolution, double i_marker_width)\r
+ {\r
+ if (this._current_arcode_index != -1) {\r
+ // 強制リセット\r
+ reset(true);\r
+ }\r
+ //検出するマーカセット、情報、検出器を作り直す。(1ピクセル4ポイントサンプリング,マーカのパターン領域は50%)\r
+ this._detectmarker_cb.setNyARCodeTable(i_ref_code_table,i_code_resolution);\r
+ this._marker_width = i_marker_width;\r
+ return;\r
+ }\r
+\r
+ public void reset(boolean i_is_force)\r
+ {\r
+ if (this._current_arcode_index != -1 && i_is_force == false) {\r
+ // 強制書き換えでなければイベントコール\r
+ this.onLeaveHandler();\r
+ }\r
+ // カレントマーカをリセット\r
+ this._current_arcode_index = -1;\r
+ return;\r
+ }\r
+ private DetectSquareCB _detectmarker_cb;\r
+ public void detectMarker(INyARRgbRaster i_raster) throws NyARException\r
+ {\r
+ // サイズチェック\r
+ assert(this._bin_raster.getSize().isEqualSize(i_raster.getSize().w, i_raster.getSize().h));\r
+\r
+ //BINイメージへの変換\r
+ this._tobin_filter.setThreshold(this._threshold);\r
+ this._tobin_filter.doFilter(i_raster, this._bin_raster);\r
+\r
+ // スクエアコードを探す\r
+ this._detectmarker_cb.init(i_raster);\r
+ this._square_detect.detectMarkerCB(this._bin_raster,this._detectmarker_cb);\r
+ \r
+ // 認識状態を更新\r
+ final boolean is_id_found=updateStatus(this._detectmarker_cb.square,this._detectmarker_cb.code_index);\r
+ //閾値フィードバック(detectExistMarkerにもあるよ)\r
+ if(!is_id_found){\r
+ //マーカがなければ、探索+DualPTailで基準輝度検索\r
+ int th=this._threshold_detect.analyzeRaster(i_raster);\r
+ this._threshold=(this._threshold+th)/2;\r
+ }\r
+ \r
+ \r
+ return;\r
+ }\r
+\r
+ private NyARTransMatResult __NyARSquare_result = new NyARTransMatResult();\r
+\r
+ /** オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。\r
+ * 戻り値は、「実際にマーカを発見する事ができたか」です。クラスの状態とは異なります。\r
+ */\r
+ private boolean updateStatus(NyARSquare i_square, int i_code_index) throws NyARException\r
+ {\r
+ NyARTransMatResult result = this.__NyARSquare_result;\r
+ if (this._current_arcode_index < 0) {// 未認識中\r
+ if (i_code_index < 0) {// 未認識から未認識の遷移\r
+ // なにもしないよーん。\r
+ return false;\r
+ } else {// 未認識から認識の遷移\r
+ this._current_arcode_index = i_code_index;\r
+ // イベント生成\r
+ // OnEnter\r
+ this.onEnterHandler(i_code_index);\r
+ // 変換行列を作成\r
+ this._transmat.transMat(i_square, this._marker_width, result);\r
+ // OnUpdate\r
+ this.onUpdateHandler(i_square, result);\r
+ this._lost_delay_count = 0;\r
+ return true;\r
+ }\r
+ } else {// 認識中\r
+ if (i_code_index < 0) {// 認識から未認識の遷移\r
+ this._lost_delay_count++;\r
+ if (this._lost_delay < this._lost_delay_count) {\r
+ // OnLeave\r
+ this._current_arcode_index = -1;\r
+ this.onLeaveHandler();\r
+ }\r
+ return false;\r
+ } else if (i_code_index == this._current_arcode_index) {// 同じARCodeの再認識\r
+ // イベント生成\r
+ // 変換行列を作成\r
+ this._transmat.transMat(i_square, this._marker_width, result);\r
+ // OnUpdate\r
+ this.onUpdateHandler(i_square, result);\r
+ this._lost_delay_count = 0;\r
+ return true;\r
+ } else {// 異なるコードの認識→今はサポートしない。\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ }\r
+\r
+ protected abstract void onEnterHandler(int i_code);\r
+\r
+ protected abstract void onLeaveHandler();\r
+\r
+ protected abstract void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result);\r
+}\r
--- /dev/null
+/* \r
+ * Capture Test NyARToolkitサンプルプログラム\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.processor;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.analyzer.raster.threshold.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilter_ARToolkitThreshold;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.data.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+\r
+public abstract class SingleNyIdMarkerProcesser\r
+{\r
+ /**\r
+ * detectMarkerのコールバック関数\r
+ */\r
+ private class DetectSquareCB implements INyARSquareContourDetector.DetectMarkerCallback\r
+ {\r
+ //公開プロパティ\r
+ public final NyARSquare square=new NyARSquare();\r
+ public INyIdMarkerData marker_data;\r
+ public int threshold;\r
+\r
+ \r
+ //参照\r
+ private INyARRgbRaster _ref_raster;\r
+ //所有インスタンス\r
+ private INyIdMarkerData _current_data;\r
+ private final NyIdMarkerPickup _id_pickup = new NyIdMarkerPickup();\r
+ private Coord2Linear _coordline;\r
+ private INyIdMarkerDataEncoder _encoder;\r
+\r
+ \r
+ private INyIdMarkerData _data_temp;\r
+ private INyIdMarkerData _prev_data;\r
+ \r
+ public DetectSquareCB(NyARParam i_param,INyIdMarkerDataEncoder i_encoder)\r
+ {\r
+ this._coordline=new Coord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());\r
+ this._data_temp=i_encoder.createDataInstance();\r
+ this._current_data=i_encoder.createDataInstance();\r
+ this._encoder=i_encoder;\r
+ return;\r
+ }\r
+ private NyARIntPoint2d[] __tmp_vertex=NyARIntPoint2d.createArray(4);\r
+ /**\r
+ * Initialize call back handler.\r
+ */\r
+ public void init(INyARRgbRaster i_raster,INyIdMarkerData i_prev_data)\r
+ {\r
+ this.marker_data=null;\r
+ this._prev_data=i_prev_data;\r
+ this._ref_raster=i_raster;\r
+ }\r
+ private final NyIdMarkerParam _marker_param=new NyIdMarkerParam();\r
+ private final NyIdMarkerPattern _marker_data=new NyIdMarkerPattern();\r
+\r
+ /**\r
+ * 矩形が見付かるたびに呼び出されます。\r
+ * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。\r
+ */\r
+ public void onSquareDetect(INyARSquareContourDetector i_sender,int[] i_coordx,int[] i_coordy,int i_coor_num,int[] i_vertex_index) throws NyARException\r
+ {\r
+ //既に発見済なら終了\r
+ if(this.marker_data!=null){\r
+ return;\r
+ }\r
+ //輪郭座標から頂点リストに変換\r
+ NyARIntPoint2d[] vertex=this.__tmp_vertex;\r
+ vertex[0].x=i_coordx[i_vertex_index[0]];\r
+ vertex[0].y=i_coordy[i_vertex_index[0]];\r
+ vertex[1].x=i_coordx[i_vertex_index[1]];\r
+ vertex[1].y=i_coordy[i_vertex_index[1]];\r
+ vertex[2].x=i_coordx[i_vertex_index[2]];\r
+ vertex[2].y=i_coordy[i_vertex_index[2]];\r
+ vertex[3].x=i_coordx[i_vertex_index[3]];\r
+ vertex[3].y=i_coordy[i_vertex_index[3]];\r
+ \r
+ NyIdMarkerParam param=this._marker_param;\r
+ NyIdMarkerPattern patt_data =this._marker_data; \r
+ // 評価基準になるパターンをイメージから切り出す\r
+ if (!this._id_pickup.pickFromRaster(this._ref_raster,vertex, patt_data, param)){\r
+ return;\r
+ }\r
+ //エンコード\r
+ if(!this._encoder.encode(patt_data,this._data_temp)){\r
+ return;\r
+ }\r
+\r
+ //継続認識要求されている?\r
+ if (this._prev_data==null){\r
+ //継続認識要求なし\r
+ this._current_data.copyFrom(this._data_temp);\r
+ }else{\r
+ //継続認識要求あり\r
+ if(!this._prev_data.isEqual((this._data_temp))){\r
+ return;//認識請求のあったIDと違う。\r
+ }\r
+ }\r
+ //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。\r
+ //ココから先はこの条件でしか実行されない。\r
+ NyARSquare sq=this.square;\r
+ //directionを考慮して、squareを更新する。\r
+ for(int i=0;i<4;i++){\r
+ int idx=(i+4 - param.direction) % 4;\r
+ sq.imvertex[i].x=vertex[idx].x;\r
+ sq.imvertex[i].y=vertex[idx].y;\r
+ this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);\r
+ }\r
+ for (int i = 0; i < 4; i++) {\r
+ //直線同士の交点計算\r
+ if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){\r
+ throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK\r
+ }\r
+ }\r
+ this.threshold=param.threshold;\r
+ this.marker_data=this._current_data;//みつかった。\r
+ }\r
+ } \r
+ /**\r
+ * オーナーが自由に使えるタグ変数です。\r
+ */\r
+ public Object tag;\r
+\r
+ /**\r
+ * ロスト遅延の管理\r
+ */\r
+ private int _lost_delay_count = 0;\r
+ private int _lost_delay = 5;\r
+\r
+ private NyARSquareContourDetector_Rle _square_detect;\r
+ protected INyARTransMat _transmat;\r
+ private double _marker_width=100;\r
+ private boolean _is_active;\r
+ private int _current_threshold=110;\r
+ // [AR]検出結果の保存用\r
+ private NyARBinRaster _bin_raster;\r
+ private NyARRasterFilter_ARToolkitThreshold _tobin_filter;\r
+ private DetectSquareCB _callback;\r
+ private INyIdMarkerData _data_current;\r
+\r
+\r
+ protected SingleNyIdMarkerProcesser()\r
+ {\r
+ return;\r
+ }\r
+ private boolean _initialized=false;\r
+ protected void initInstance(NyARParam i_param,INyIdMarkerDataEncoder i_encoder,int i_raster_format) throws NyARException\r
+ {\r
+ //初期化済?\r
+ assert this._initialized==false;\r
+ \r
+ NyARIntSize scr_size = i_param.getScreenSize();\r
+ // 解析オブジェクトを作る\r
+ this._square_detect = new NyARSquareContourDetector_Rle(i_param.getDistortionFactor(), scr_size);\r
+ this._transmat = new NyARTransMat(i_param);\r
+ this._callback=new DetectSquareCB(i_param,i_encoder);\r
+\r
+ // 2値画像バッファを作る\r
+ this._bin_raster = new NyARBinRaster(scr_size.w, scr_size.h);\r
+ //ワーク用のデータオブジェクトを2個作る\r
+ this._data_current=i_encoder.createDataInstance();\r
+ this._tobin_filter =new NyARRasterFilter_ARToolkitThreshold(110,i_raster_format);\r
+ this._threshold_detect=new NyARRasterThresholdAnalyzer_SlidePTile(15,i_raster_format,4);\r
+ this._initialized=true;\r
+ this._is_active=false;\r
+ return;\r
+ \r
+ }\r
+\r
+ public void setMarkerWidth(int i_width)\r
+ {\r
+ this._marker_width=i_width;\r
+ return;\r
+ }\r
+\r
+ public void reset(boolean i_is_force)\r
+ {\r
+ if (i_is_force == false && this._is_active){\r
+ // 強制書き換えでなければイベントコール\r
+ this.onLeaveHandler();\r
+ }\r
+ //マーカ無効\r
+ this._is_active=false;\r
+ return;\r
+ }\r
+\r
+ public void detectMarker(INyARRgbRaster i_raster) throws NyARException\r
+ {\r
+ // サイズチェック\r
+ if (!this._bin_raster.getSize().isEqualSize(i_raster.getSize().w, i_raster.getSize().h)) {\r
+ throw new NyARException();\r
+ }\r
+ // ラスタを2値イメージに変換する.\r
+ this._tobin_filter.setThreshold(this._current_threshold);\r
+ this._tobin_filter.doFilter(i_raster, this._bin_raster);\r
+\r
+ // スクエアコードを探す(第二引数に指定したマーカ、もしくは新しいマーカを探す。)\r
+ this._callback.init(i_raster,this._is_active?this._data_current:null);\r
+ this._square_detect.detectMarkerCB(this._bin_raster, this._callback);\r
+\r
+ // 認識状態を更新(マーカを発見したなら、current_dataを渡すかんじ)\r
+ final boolean is_id_found=updateStatus(this._callback.square,this._callback.marker_data);\r
+\r
+ //閾値フィードバック(detectExistMarkerにもあるよ)\r
+ if(is_id_found){\r
+ //マーカがあれば、マーカの周辺閾値を反映\r
+ this._current_threshold=(this._current_threshold+this._callback.threshold)/2;\r
+ }else{\r
+ //マーカがなければ、探索+DualPTailで基準輝度検索\r
+ int th=this._threshold_detect.analyzeRaster(i_raster);\r
+ this._current_threshold=(this._current_threshold+th)/2;\r
+ } \r
+ return;\r
+ }\r
+\r
+ \r
+ private NyARRasterThresholdAnalyzer_SlidePTile _threshold_detect;\r
+ private NyARTransMatResult __NyARSquare_result = new NyARTransMatResult();\r
+\r
+ /**オブジェクトのステータスを更新し、必要に応じてハンドル関数を駆動します。\r
+ */\r
+ private boolean updateStatus(NyARSquare i_square, INyIdMarkerData i_marker_data) throws NyARException\r
+ {\r
+ boolean is_id_found=false;\r
+ NyARTransMatResult result = this.__NyARSquare_result;\r
+ if (!this._is_active) {// 未認識中\r
+ if (i_marker_data==null) {// 未認識から未認識の遷移\r
+ // なにもしないよーん。\r
+ this._is_active=false;\r
+ } else {// 未認識から認識の遷移\r
+ this._data_current.copyFrom(i_marker_data);\r
+ // イベント生成\r
+ // OnEnter\r
+ this.onEnterHandler(this._data_current);\r
+ // 変換行列を作成\r
+ this._transmat.transMat(i_square, this._marker_width, result);\r
+ // OnUpdate\r
+ this.onUpdateHandler(i_square, result);\r
+ this._lost_delay_count = 0;\r
+ this._is_active=true;\r
+ is_id_found=true;\r
+ }\r
+ } else {// 認識中\r
+ if (i_marker_data==null) {\r
+ // 認識から未認識の遷移\r
+ this._lost_delay_count++;\r
+ if (this._lost_delay < this._lost_delay_count) {\r
+ // OnLeave\r
+ this.onLeaveHandler();\r
+ this._is_active=false;\r
+ }\r
+ } else if(this._data_current.isEqual(i_marker_data)) {\r
+ //同じidの再認識\r
+ this._transmat.transMat(i_square, this._marker_width, result);\r
+ // OnUpdate\r
+ this.onUpdateHandler(i_square, result);\r
+ this._lost_delay_count = 0;\r
+ is_id_found=true;\r
+ } else {// 異なるコードの認識→今はサポートしない。\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ return is_id_found;\r
+ } \r
+ //通知ハンドラ\r
+ protected abstract void onEnterHandler(INyIdMarkerData i_code);\r
+ protected abstract void onLeaveHandler();\r
+ protected abstract void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result);\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sample;\r
+\r
+import java.io.*;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.data.*;\r
+import jp.nyatla.nyartoolkit.processor.*;\r
+\r
+/**\r
+ * 320x240のBGRA32で記録されたIdmarkerを撮影したRAWイメージから、\r
+ * Idマーカを認識します。\r
+ *\r
+ */\r
+public class NyIdTest\r
+{\r
+ public class MarkerProcessor extends SingleNyIdMarkerProcesser\r
+ {\r
+ private Object _sync_object = new Object();\r
+ public NyARTransMatResult transmat = null;\r
+ public int current_id = -1;\r
+\r
+ public MarkerProcessor(NyARParam i_cparam, int i_raster_format) throws Exception\r
+ {\r
+ super();//\r
+ initInstance(i_cparam, new NyIdMarkerDataEncoder_RawBit(), i_raster_format);\r
+ //アプリケーションフレームワークの初期化\r
+ return;\r
+ }\r
+ /**\r
+ * アプリケーションフレームワークのハンドラ(マーカ出現)\r
+ */\r
+ protected void onEnterHandler(INyIdMarkerData i_code)\r
+ {\r
+ synchronized (this._sync_object)\r
+ {\r
+ NyIdMarkerData_RawBit code = (NyIdMarkerData_RawBit)i_code;\r
+ if (code.length > 4)\r
+ {\r
+ //4バイト以上の時はint変換しない。\r
+ this.current_id = -1;//undefined_id\r
+ }\r
+ else\r
+ {\r
+ this.current_id = 0;\r
+ //最大4バイト繋げて1個のint値に変換\r
+ for (int i = 0; i < code.length; i++)\r
+ {\r
+ this.current_id = (this.current_id << 8) | code.packet[i];\r
+ }\r
+ }\r
+ this.transmat = null;\r
+ }\r
+ }\r
+ /**\r
+ * アプリケーションフレームワークのハンドラ(マーカ消滅)\r
+ */\r
+ protected void onLeaveHandler()\r
+ {\r
+ synchronized (this._sync_object)\r
+ {\r
+ this.current_id = -1;\r
+ this.transmat = null;\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * アプリケーションフレームワークのハンドラ(マーカ更新)\r
+ */\r
+ protected void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result)\r
+ {\r
+ synchronized (this._sync_object)\r
+ {\r
+ this.transmat = result;\r
+ }\r
+ }\r
+ }\r
+ private final String data_file = "../Data/320x240NyId.raw";\r
+ private final String camera_file = "../Data/camera_para.dat";\r
+ public NyIdTest()\r
+ {\r
+ }\r
+ public void Test() throws Exception\r
+ {\r
+ //AR用カメラパラメタファイルをロード\r
+ NyARParam ap = new NyARParam();\r
+ ap.loadARParamFromFile(camera_file);\r
+ ap.changeScreenSize(320, 240);\r
+\r
+ // 試験イメージの読み出し(320x240 BGRAのRAWデータ)\r
+ File f = new File(data_file);\r
+ FileInputStream fs = new FileInputStream(data_file);\r
+ byte[] buf = new byte[(int) f.length()];\r
+ fs.read(buf); \r
+\r
+ NyARRgbRaster_RGB ra = NyARRgbRaster_RGB.wrap(buf, 320, 240);\r
+\r
+ MarkerProcessor pr = new MarkerProcessor(ap, ra.getBufferReader().getBufferType());\r
+ pr.detectMarker(ra);\r
+ return;\r
+ }\r
+ public static void main(String[] args)\r
+ {\r
+\r
+ try {\r
+ NyIdTest t = new NyIdTest();\r
+ // t.Test_arGetVersion();\r
+ t.Test();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ } \r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sample;\r
+\r
+import java.io.*;\r
+import java.util.*;\r
+\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.detector.NyARSingleDetectMarker;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * 320x240のBGRA32で記録されたRAWイメージから、1種類のパターンを認識し、\r
+ * その変換行列を1000回求め、それにかかったミリ秒時間を表示します。\r
+ * \r
+ */\r
+public class RawFileTest\r
+{\r
+ private final String code_file = "../Data/patt.hiro";\r
+\r
+ private final String data_file = "../Data/320x240ABGR.raw";\r
+\r
+ private final String camera_file = "../Data/camera_para.dat";\r
+\r
+ public RawFileTest()\r
+ {\r
+ }\r
+\r
+\r
+ public void Test_arDetectMarkerLite() throws Exception\r
+ {\r
+ // AR用カメラパラメタファイルをロード\r
+ NyARParam ap = new NyARParam();\r
+ ap.loadARParamFromFile(camera_file);\r
+ ap.changeScreenSize(320, 240);\r
+\r
+ // AR用のパターンコードを読み出し\r
+ NyARCode code = new NyARCode(16, 16);\r
+ code.loadARPattFromFile(code_file);\r
+\r
+ // 試験イメージの読み出し(320x240 BGRAのRAWデータ)\r
+ File f = new File(data_file);\r
+ FileInputStream fs = new FileInputStream(data_file);\r
+ byte[] buf = new byte[(int) f.length()];\r
+ fs.read(buf);\r
+ INyARRgbRaster ra = NyARRgbRaster_BGRA.wrap(buf, 320, 240);\r
+ // Blank_Raster ra=new Blank_Raster(320, 240);\r
+\r
+ // 1パターンのみを追跡するクラスを作成\r
+ NyARSingleDetectMarker ar = new NyARSingleDetectMarker(\r
+ ap, code, 80.0,ra.getBufferReader().getBufferType(),NyARSingleDetectMarker.PF_NYARTOOLKIT);\r
+ NyARTransMatResult result_mat = new NyARTransMatResult();\r
+ ar.setContinueMode(false);\r
+ ar.detectMarkerLite(ra, 100);\r
+ ar.getTransmationMatrix(result_mat);\r
+\r
+ // マーカーを検出\r
+ Date d2 = new Date();\r
+ for (int i = 0; i < 1000; i++) {\r
+ // 変換行列を取得\r
+ ar.detectMarkerLite(ra, 100);\r
+ ar.getTransmationMatrix(result_mat);\r
+ }\r
+ Date d = new Date();\r
+ NyARDoublePoint3d ang=new NyARDoublePoint3d();\r
+ result_mat.getZXYAngle(ang);\r
+ System.out.println(d.getTime() - d2.getTime());\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+\r
+ try {\r
+ RawFileTest t = new RawFileTest();\r
+ // t.Test_arGetVersion();\r
+ t.Test_arDetectMarkerLite();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.sample;\r
+\r
+import java.io.*;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.processor.*;\r
+\r
+public class SingleARMarkerTest\r
+{\r
+ class MarkerProcessor extends SingleARMarkerProcesser\r
+ { \r
+ private Object _sync_object=new Object();\r
+ public NyARTransMatResult transmat=null;\r
+ public int current_code=-1;\r
+\r
+ public MarkerProcessor(NyARParam i_cparam,int i_raster_format) throws NyARException\r
+ {\r
+ //アプリケーションフレームワークの初期化\r
+ super();\r
+ initInstance(i_cparam,i_raster_format);\r
+ return;\r
+ }\r
+ protected void onEnterHandler(int i_code)\r
+ {\r
+ synchronized(this._sync_object){\r
+ current_code=i_code;\r
+ }\r
+ }\r
+ protected void onLeaveHandler()\r
+ {\r
+ synchronized(this._sync_object){\r
+ current_code=-1;\r
+ this.transmat=null;\r
+ }\r
+ return; \r
+ }\r
+\r
+ protected void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result)\r
+ {\r
+ synchronized(this._sync_object){\r
+ this.transmat=result;\r
+ } \r
+ }\r
+ }\r
+ private final static String CARCODE_FILE = "../Data/patt.hiro";\r
+ private final static String PARAM_FILE = "../Data/camera_para.dat"; \r
+ private final String data_file = "../Data/320x240ABGR.raw";\r
+\r
+ public SingleARMarkerTest()\r
+ {\r
+ }\r
+ public void Test() throws Exception\r
+ {\r
+ //AR用カメラパラメタファイルをロード\r
+ NyARParam ap = new NyARParam();\r
+ ap.loadARParamFromFile(PARAM_FILE);\r
+ ap.changeScreenSize(320, 240);\r
+\r
+ // 試験イメージの読み出し(320x240 BGRAのRAWデータ)\r
+ File f = new File(data_file);\r
+ FileInputStream fs = new FileInputStream(data_file);\r
+ byte[] buf = new byte[(int) f.length()];\r
+ fs.read(buf); \r
+\r
+ NyARRgbRaster_BGRA ra = NyARRgbRaster_BGRA.wrap(buf, 320, 240);\r
+\r
+ MarkerProcessor pr = new MarkerProcessor(ap, ra.getBufferReader().getBufferType());\r
+ NyARCode[] codes=new NyARCode[1];\r
+ codes[0]=new NyARCode(16,16);\r
+ codes[0].loadARPattFromFile(CARCODE_FILE);\r
+ pr.setARCodeTable(codes,16,80.0);\r
+ pr.detectMarker(ra);\r
+ return;\r
+ }\r
+ public static void main(String[] args)\r
+ {\r
+\r
+ try {\r
+ SingleARMarkerTest t = new SingleARMarkerTest();\r
+ // t.Test_arGetVersion();\r
+ t.Test();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ } \r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.utils;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.param.NyARPerspectiveProjectionMatrix;\r
+import jp.nyatla.nyartoolkit.core.pickup.NyARColorPatt_Perspective_O2;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;\r
+import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+\r
+/**\r
+ * マーカの周辺領域からビットマップを取得する方法を提供します。\r
+ * 比較的負荷が大きいので、連続してパターンを取得し続ける用途には向いていません。\r
+ *\r
+ */\r
+class TransformedBitmapPickup extends NyARColorPatt_Perspective_O2\r
+{\r
+ private NyARIntPoint2d[] _work_points = NyARIntPoint2d.createArray(4);\r
+\r
+ private NyARPerspectiveProjectionMatrix _ref_perspective;\r
+\r
+ /**\r
+ * \r
+ * @param i_width\r
+ * 取得するビットマップの幅\r
+ * @param i_height\r
+ * 取得するビットマップの解像度\r
+ * @param i_resolution\r
+ * resolution of reading pixel per point. ---- 取得時の解像度。高解像度のときは1を指定してください。低解像度のときは2以上を指定します。\r
+ */\r
+ TransformedBitmapPickup(NyARPerspectiveProjectionMatrix i_ref_cparam, int i_width, int i_height, int i_resolution)\r
+ {\r
+ super(i_width, i_height, i_resolution, 0);\r
+ this._ref_perspective = i_ref_cparam;\r
+ }\r
+\r
+ /**\r
+ * This function retrieves bitmap from the area defined by RECT(i_l,i_t,i_r,i_b) above transform matrix i_base_mat. \r
+ * ----\r
+ * この関数は、basementで示される平面のAで定義される領域から、ビットマップを読み出します。\r
+ * 例えば、8cmマーカでRECT(i_l,i_t,i_r,i_b)に-40,0,0,-40.0を指定すると、マーカの左下部分の画像を抽出します。\r
+ * \r
+ * マーカから離れた場所になるほど、また、マーカの鉛直方向から外れるほど誤差が大きくなります。\r
+ * @param i_src_imege\r
+ * 詠み出し元の画像を指定します。\r
+ * @param i_l\r
+ * 基準点からの左上の相対座標(x)を指定します。\r
+ * @param i_t\r
+ * 基準点からの左上の相対座標(y)を指定します。\r
+ * @param i_r\r
+ * 基準点からの右下の相対座標(x)を指定します。\r
+ * @param i_b\r
+ * 基準点からの右下の相対座標(y)を指定します。\r
+ * @param i_base_mat\r
+ * @return 画像の取得の成否を返す。\r
+ */\r
+ public boolean pickupImage2d(INyARRgbRaster i_src_imege, double i_l, double i_t, double i_r, double i_b, NyARTransMatResult i_base_mat) throws NyARException\r
+ {\r
+ double cp00, cp01, cp02, cp11, cp12;\r
+ cp00 = this._ref_perspective.m00;\r
+ cp01 = this._ref_perspective.m01;\r
+ cp02 = this._ref_perspective.m02;\r
+ cp11 = this._ref_perspective.m11;\r
+ cp12 = this._ref_perspective.m12;\r
+ //マーカと同一平面上にある矩形の4個の頂点を座標変換して、射影変換して画面上の\r
+ //頂点を計算する。\r
+ //[hX,hY,h]=[P][RT][x,y,z]\r
+\r
+ //出力先\r
+ NyARIntPoint2d[] poinsts = this._work_points; \r
+ \r
+ double yt0,yt1,yt2;\r
+ double x3, y3, z3;\r
+ \r
+ double m00=i_base_mat.m00;\r
+ double m10=i_base_mat.m10;\r
+ double m20=i_base_mat.m20;\r
+ \r
+ //yとtの要素を先に計算\r
+ yt0=i_base_mat.m01 * i_t+i_base_mat.m03;\r
+ yt1=i_base_mat.m11 * i_t+i_base_mat.m13;\r
+ yt2=i_base_mat.m21 * i_t+i_base_mat.m23;\r
+ // l,t\r
+ x3 = m00 * i_l + yt0;\r
+ y3 = m10 * i_l + yt1;\r
+ z3 = m20 * i_l + yt2;\r
+ poinsts[0].x = (int) ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);\r
+ poinsts[0].y = (int) ((y3 * cp11 + z3 * cp12) / z3);\r
+ // r,t\r
+ x3 = m00 * i_r + yt0;\r
+ y3 = m10 * i_r + yt1;\r
+ z3 = m20 * i_r + yt2;\r
+ poinsts[1].x = (int) ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);\r
+ poinsts[1].y = (int) ((y3 * cp11 + z3 * cp12) / z3);\r
+\r
+ //yとtの要素を先に計算\r
+ yt0=i_base_mat.m01 * i_b+i_base_mat.m03;\r
+ yt1=i_base_mat.m11 * i_b+i_base_mat.m13;\r
+ yt2=i_base_mat.m21 * i_b+i_base_mat.m23;\r
+\r
+ // r,b\r
+ x3 = m00 * i_r + yt0;\r
+ y3 = m10 * i_r + yt1;\r
+ z3 = m20 * i_r + yt2;\r
+ poinsts[2].x = (int) ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);\r
+ poinsts[2].y = (int) ((y3 * cp11 + z3 * cp12) / z3);\r
+ // l,b\r
+ x3 = m00 * i_l + yt0;\r
+ y3 = m10 * i_l + yt1;\r
+ z3 = m20 * i_l + yt2;\r
+ poinsts[3].x = (int) ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);\r
+ poinsts[3].y = (int) ((y3 * cp11 + z3 * cp12) / z3);\r
+ return this.pickFromRaster(i_src_imege, poinsts);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.utils.j2se;\r
+\r
+import java.awt.Graphics;\r
+import java.awt.image.*;\r
+import java.awt.color.*;\r
+import java.awt.*;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.stack.*;\r
+import jp.nyatla.nyartoolkit.core.labeling.*;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;\r
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;\r
+\r
+/**\r
+ * bitmapとして利用可能なラベリングイメージです。\r
+ * \r
+ * \r
+ */\r
+public class LabelingBufferdImage extends BufferedImage\r
+{\r
+ public final static int COLOR_125_COLOR = 0;// 125色ラベルモード\r
+\r
+ public final static int COLOR_256_MONO = 1;// 64階調モノクロモード\r
+\r
+ public final static int COLOR_64_MONO = 2;// 64階調モノクロモード\r
+\r
+ public final static int COLOR_32_MONO = 3;// 32階調モノクロモード\r
+\r
+ public final static int COLOR_16_MONO = 4;// 16階調モノクロモード\r
+\r
+ public final static int COLOR_8_MONO = 5;// 16階調モノクロモード\r
+\r
+ private int[] _rgb_table_125;\r
+\r
+\r
+ /**\r
+ * i_width x i_heightの大きさのイメージを作成します。\r
+ * \r
+ * @param i_width\r
+ * @param i_height\r
+ */\r
+ public LabelingBufferdImage(int i_width, int i_height)\r
+ {\r
+ super(i_width, i_height, ColorSpace.TYPE_RGB);\r
+ // RGBテーブルを作成\r
+ this._rgb_table_125 = new int[125];\r
+ for (int i = 0; i < 5; i++) {\r
+ for (int i2 = 0; i2 < 5; i2++) {\r
+ for (int i3 = 0; i3 < 5; i3++) {\r
+ this._rgb_table_125[((i * 5) + i2) * 5 + i3] = ((((i * 63) << 8) | (i2 * 63)) << 8) | (i3 * 63);\r
+ }\r
+ }\r
+ }\r
+/* case COLOR_256_MONO:\r
+ this._rgb_table = new int[256];\r
+ this._number_of_color = 256;\r
+ for (int i = 0; i < 256; i++) {\r
+ this._rgb_table[i] = (i << 16) | (i << 8) | i;\r
+ }\r
+ break;\r
+ case COLOR_64_MONO:\r
+ this._rgb_table = new int[64];\r
+ this._number_of_color = 64;\r
+ for (int i = 0; i < 64; i++) {\r
+ int m = (i * 4);\r
+ this._rgb_table[i] = (m << 16) | (m << 8) | m;\r
+ }\r
+ break;\r
+ case COLOR_32_MONO:\r
+ this._rgb_table = new int[32];\r
+ this._number_of_color = 32;\r
+ for (int i = 0; i < 32; i++) {\r
+ int m = (i * 8);\r
+ this._rgb_table[i] = (m << 16) | (m << 8) | m;\r
+ }\r
+ break;\r
+ case COLOR_16_MONO:\r
+ this._rgb_table = new int[32];\r
+ this._number_of_color = 16;\r
+ for (int i = 0; i < 16; i++) {\r
+ int m = (i * 8);\r
+ this._rgb_table[i] = (m << 16) | (m << 8) | m;\r
+ }\r
+ break;\r
+ }*/\r
+ }\r
+\r
+\r
+\r
+ public void drawImage(NyARGrayscaleRaster i_raster) throws NyARException\r
+ {\r
+ assert (i_raster.getBufferReader().getBufferType() == INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8);\r
+\r
+ int w = this.getWidth();\r
+ int h = this.getHeight();\r
+ // サイズをチェック\r
+ NyARIntSize size = i_raster.getSize();\r
+ if (size.h > h || size.w > w) {\r
+ throw new NyARException();\r
+ }\r
+\r
+ int[] limg;\r
+ // イメージの描画\r
+ limg = (int[]) i_raster.getBufferReader().getBuffer();\r
+ for (int i = 0; i < h; i++) {\r
+ for (int i2 = 0; i2 < w; i2++) {\r
+ this.setRGB(i2, i,limg[i*w+i2]);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * バイナリラスタ\r
+ * @param i_raster\r
+ * @throws NyARException\r
+ */\r
+ public void drawImage(NyARBinRaster i_raster) throws NyARException\r
+ {\r
+ assert (i_raster.getBufferReader().getBufferType() == INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8);\r
+\r
+ int w = this.getWidth();\r
+ int h = this.getHeight();\r
+ // サイズをチェック\r
+ NyARIntSize size = i_raster.getSize();\r
+ if (size.h > h || size.w > w) {\r
+ throw new NyARException();\r
+ }\r
+\r
+ int[] limg;\r
+ // イメージの描画\r
+ limg = (int[]) i_raster.getBufferReader().getBuffer();\r
+ for (int i = 0; i < h; i++) {\r
+ for (int i2 = 0; i2 < w; i2++) {\r
+ this.setRGB(i2, i, limg[i*w+i2] > 0 ? 255 : 0);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ \r
+ /**\r
+ * ラベリングイメージを書く\r
+ * @param i_raster\r
+ * @throws NyARException\r
+ */\r
+ public void drawLabel(NyARLabelingImage i_image) throws NyARException\r
+ {\r
+ int w = this.getWidth();\r
+ int h = this.getHeight();\r
+ // サイズをチェック\r
+ NyARIntSize size = i_image.getSize();\r
+ if (size.h > h || size.w > w) {\r
+ throw new NyARException();\r
+ }\r
+ int[] index_array=i_image.getIndexArray();\r
+\r
+ int[] limg;\r
+ // イメージの描画\r
+ limg = (int[]) i_image.getBufferReader().getBuffer();\r
+ for (int i = 0; i < h; i++) {\r
+ for (int i2 = 0; i2 < w; i2++) {\r
+ int t=limg[i*w+i2]-1;\r
+ if(t<0){\r
+ t=0;\r
+ }else{\r
+ t=index_array[t];\r
+ }\r
+ this.setRGB(i2, i,_rgb_table_125[t% _rgb_table_125.length]);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * \r
+ * @param i_stack\r
+ */\r
+\r
+ public void overlayData(NyARLabelingLabel i_label)\r
+ {\r
+ Graphics g = this.getGraphics();\r
+ g.setColor(Color.red);\r
+ g.drawRect(i_label.clip_l,i_label.clip_t,i_label.clip_r-i_label.clip_l,i_label.clip_b-i_label.clip_t);\r
+ return;\r
+ } \r
+ /**\r
+ * \r
+ * @param i_stack\r
+ */\r
+\r
+ public void overlayData(NyARIntPointStack i_stack)\r
+ {\r
+ int count = i_stack.getLength();\r
+ NyARIntPoint2d[] items = i_stack.getArray();\r
+ Graphics g = this.getGraphics();\r
+ for (int i = 0; i < count; i++) {\r
+ int x = items[i].x;\r
+ int y = items[i].y;\r
+ g.setColor(Color.red);\r
+ g.drawLine(x - 5, y, x + 5, y);\r
+ g.drawLine(x, y + 5, x, y - 5);\r
+ }\r
+ return;\r
+ }\r
+ public void overlayData(NyARIntRectStack i_stack)\r
+ {\r
+ Color[] c=new Color[]{Color.cyan,Color.red,Color.green};\r
+ int count = i_stack.getLength();\r
+ NyARIntRect[] items = i_stack.getArray();\r
+ Graphics g = this.getGraphics();\r
+ for (int i = 0; i < count; i++) {\r
+ int x = items[i].x;\r
+ int y = items[i].y;\r
+ g.setColor(c[i%1]);\r
+ g.drawRect(x,y,items[i].w,items[i].h);\r
+ }\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.utils.j2se;\r
+\r
+import java.awt.Graphics.*;\r
+import java.awt.image.*;\r
+import java.awt.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+\r
+/**\r
+ * BufferdImageとRasterイメージ間で、ビットマップをコピーします。\r
+ */\r
+public class NyARRasterImageIO\r
+{\r
+ /**\r
+ * i_inの内容を、このイメージにコピーします。\r
+ * @param i_in\r
+ * @throws NyARException\r
+ */\r
+ public static void copy(INyARRgbRaster i_in,BufferedImage o_out) throws NyARException\r
+ {\r
+ assert i_in.getSize().isEqualSize(o_out.getWidth(), o_out.getHeight());\r
+ \r
+ //thisへ転写\r
+ INyARRgbPixelReader reader=i_in.getRgbPixelReader();\r
+ int[] rgb=new int[3];\r
+\r
+ for(int y=o_out.getHeight()-1;y>=0;y--){\r
+ for(int x=o_out.getWidth()-1;x>=0;x--){\r
+ reader.getPixel(x,y,rgb);\r
+ o_out.setRGB(x,y,(rgb[0]<<16)|(rgb[1]<<8)|rgb[2]);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * GrayScale用\r
+ * @param i_in\r
+ * @throws NyARException\r
+ */\r
+ public static void copy(NyARGrayscaleRaster i_in,BufferedImage o_out) throws NyARException\r
+ {\r
+ assert i_in.getSize().isEqualSize(o_out.getWidth(), o_out.getHeight());\r
+ if(i_in.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_GRAY_8))\r
+ {\r
+ final int[] buf=(int[])i_in.getBufferReader().getBuffer();\r
+ final int w=o_out.getWidth();\r
+ final int h=o_out.getHeight();\r
+ for(int y=h-1;y>=0;y--){\r
+ for(int x=w-1;x>=0;x--){\r
+ int v=buf[x+y*w];\r
+ o_out.setRGB(x, y,v*(1+0x100+0x10000));\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ } \r
+ /**\r
+ * BIN_8用\r
+ * @param i_in\r
+ * @throws NyARException\r
+ */\r
+ public static void copy(INyARRaster i_in,BufferedImage o_out) throws NyARException\r
+ {\r
+ assert i_in.getSize().isEqualSize(o_out.getWidth(), o_out.getHeight());\r
+ if(i_in.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8))\r
+ {\r
+ final int[] buf=(int[])i_in.getBufferReader().getBuffer();\r
+ final int w=o_out.getWidth();\r
+ final int h=o_out.getHeight();\r
+ for(int y=h-1;y>=0;y--){\r
+ for(int x=w-1;x>=0;x--){\r
+ o_out.setRGB(x, y,buf[x+y*w]==0?0:0xffffff);\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ } \r
+ /**\r
+ * ヒストグラムを書き出します。\r
+ * @param i_in\r
+ * @param o_out\r
+ * @throws NyARException\r
+ */\r
+ public static void copy(NyARHistgram i_in,int i_l,int i_t,int i_h,Graphics i_g) throws NyARException\r
+ {\r
+ //正規化のための定数を出す。\r
+ int max=0;\r
+ for(int i=0;i<i_in.length;i++){\r
+ max=max<i_in.data[i]?i_in.data[i]:max;\r
+ }\r
+ if(max==0){\r
+ return;\r
+ }\r
+ //ヒストグラムを書く\r
+ for(int i=0;i<i_in.length;i++){\r
+ i_g.drawLine(i_l+i,i_t,i_l+i,i_h-i_h*i_in.data[i]/max);\r
+ }\r
+ return;\r
+ } \r
+ /**\r
+ * i_outへこのイメージを出力します。\r
+ * \r
+ * @param i_out\r
+ * @throws NyARException\r
+ */\r
+ public static void copy(BufferedImage i_in,INyARRgbRaster o_out) throws NyARException\r
+ {\r
+ assert o_out.getSize().isEqualSize(i_in.getWidth(), i_in.getHeight());\r
+ \r
+ //thisへ転写\r
+ INyARRgbPixelReader reader=o_out.getRgbPixelReader();\r
+ int[] rgb=new int[3];\r
+ for(int y=i_in.getHeight()-1;y>=0;y--){\r
+ for(int x=i_in.getWidth()-1;x>=0;x--){\r
+ int pix=i_in.getRGB(x, y);\r
+ rgb[0]=(pix>>16)&0xff;\r
+ rgb[1]=(pix>>8)&0xff;\r
+ rgb[2]=(pix)&0xff;\r
+ reader.setPixel(x,y,rgb);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * BIN_8用\r
+ * @param i_in\r
+ * @throws NyARException\r
+ */\r
+ public static void copy(BufferedImage i_in,INyARRaster o_out) throws NyARException\r
+ {\r
+ assert o_out.getSize().isEqualSize(i_in.getWidth(), i_in.getHeight());\r
+ if(o_out.getBufferReader().isEqualBufferType(INyARBufferReader.BUFFERFORMAT_INT1D_BIN_8))\r
+ {\r
+ final int[] buf=(int[])o_out.getBufferReader().getBuffer();\r
+ final int w=i_in.getWidth();\r
+ final int h=i_in.getHeight();\r
+ for(int y=h-1;y>=0;y--){\r
+ for(int x=w-1;x>=0;x--){\r
+ buf[x+y*w]=(i_in.getRGB(x, y)&0xffffff)>0?1:0;\r
+ }\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ \r
+}\r
--- /dev/null
+/* このソースは実験用のソースです。
+ * 動いたり動かなかったりします。
+ *
+ */
+package jp.nyatla.nyartoolkit.dev;
+
+import javax.media.*;
+
+import javax.media.util.BufferToImage;
+import javax.media.format.*;
+
+import jp.nyatla.nyartoolkit.NyARException;
+import jp.nyatla.nyartoolkit.jmf.utils.*;
+
+import jp.nyatla.nyartoolkit.core.*;
+
+import java.awt.*;
+
+import jp.nyatla.nyartoolkit.core.labeling.*;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingImage;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabel;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabelingLabelStack;
+import jp.nyatla.nyartoolkit.core.labeling.artoolkit.NyARLabeling_ARToolKit;
+import jp.nyatla.nyartoolkit.core.match.*;
+import jp.nyatla.nyartoolkit.core.param.*;
+import jp.nyatla.nyartoolkit.core.pca2d.INyARPca2d;
+import jp.nyatla.nyartoolkit.core.pca2d.NyARPca2d_MatrixPCA_O2;
+import jp.nyatla.nyartoolkit.core.pickup.*;
+import jp.nyatla.nyartoolkit.core.raster.*;
+import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;
+import jp.nyatla.nyartoolkit.core.rasterfilter.*;
+import jp.nyatla.nyartoolkit.core2.rasteranalyzer.*;
+import jp.nyatla.nyartoolkit.core2.rasteranalyzer.threshold.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.gs2bin.*;
+import jp.nyatla.nyartoolkit.core2.rasterfilter.rgb2gs.NyARRasterFilter_RgbAve;
+import jp.nyatla.utils.j2se.LabelingBufferdImage;
+import jp.nyatla.nyartoolkit.core.rasterfilter.bin.INyARRasterFilter_RgbToGs;
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.*;
+import jp.nyatla.nyartoolkit.core.squaredetect.INyARSquareDetector;
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquareStack;
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARVertexCounter;
+import jp.nyatla.nyartoolkit.core.transmat.*;
+import jp.nyatla.nyartoolkit.core.types.*;
+import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix22;
+import jp.nyatla.nyartoolkit.core.types.stack.NyObjectStack;
+
+
+///**
+// * QRコードのシンボルを結びつける偉いクラス
+// *
+// */
+//class NyQrCodeSymbolBinder
+//{
+// LabelingBufferdImage bimg;
+//
+// NyARIntPoint[][] _sqare;
+// /**
+// * 最小の三角形を構成する頂点セットを得る
+// * @param i_s0
+// * @param i_s1
+// * @param i_s2
+// * @param o_vertex
+// */
+// public static void getMinimumTriangleVertex(NyARSquare[] i_sqare,int[] o_vertex_id)
+// {
+// //辺の長さが最小になる頂点の組合せを探す
+// int d;
+// int x,y;
+// int dmax=0x7fffffff;
+// final NyARIntPoint[] vertex0=i_sqare[0].imvertex;
+// final NyARIntPoint[] vertex1=i_sqare[1].imvertex;
+// final NyARIntPoint[] vertex2=i_sqare[2].imvertex;
+// for(int i=0;i<4;i++)
+// {
+// for(int i2=0;i2<4;i2++)
+// {
+// for(int i3=0;i3<4;i3++){
+// x=vertex0[i].x-vertex2[i3].x;
+// y=vertex0[i].y-vertex2[i3].y;
+// d=x*x+y*y;
+// x=vertex1[i2].x-vertex2[i3].x;
+// y=vertex1[i2].y-vertex2[i3].y;
+// d+=x*x+y*y;
+// x=vertex1[i2].x-vertex0[i].x;
+// y=vertex1[i2].y-vertex0[i].y;
+// d+=x*x+y*y;
+// if(d<dmax){
+// dmax=d;
+// o_vertex_id[0]=i;
+// o_vertex_id[1]=i2;
+// o_vertex_id[2]=i3;
+// }
+// }
+// }
+// }
+// return;
+// }
+// /**
+// * 2矩形の頂点距離が最低の組合せを探す
+// * @param i_sqare
+// * @param o_vertex_id
+// */
+// public static void getMinimumLineVertex(NyARIntPoint[] i_sqare0,NyARIntPoint[] i_sqare1,int[] o_vertex_id)
+// {
+// //辺の長さが最小になる頂点の組合せを探す
+// int d;
+// int x,y;
+// int dmax=0x7fffffff;
+// for(int i=0;i<4;i++)
+// {
+// for(int i2=0;i2<4;i2++)
+// {
+// x=i_sqare1[i2].x-i_sqare0[i].x;
+// y=i_sqare1[i2].y-i_sqare0[i].y;
+// d=x*x+y*y;
+// if(d<dmax){
+// dmax=d;
+// o_vertex_id[0]=i;
+// o_vertex_id[1]=i2;
+// }
+// }
+// }
+// return;
+// }
+//
+// /**
+// * キーシンボルのインデックスを得る
+// * @param i_sqare
+// * @param i_vertex_id
+// * 最小三角形の頂点IDセット
+// * @return
+// */
+// public static int getKeySymble(NyARSquare[] i_sqare,int[] i_vertex_id)
+// {
+// //シンボルグループの重心を計算
+// int cx,cy;
+// cx=cy=0;
+// for(int i=0;i<3;i++)
+// {
+// final NyARIntPoint[] sq_ptr=i_sqare[i].imvertex;
+// cx+=sq_ptr[0].x;
+// cx+=sq_ptr[1].x;
+// cx+=sq_ptr[2].x;
+// cx+=sq_ptr[3].x;
+// cy+=sq_ptr[0].y;
+// cy+=sq_ptr[1].y;
+// cy+=sq_ptr[2].y;
+// cy+=sq_ptr[3].y;
+// }
+// cx/=12;
+// cy/=12;
+// //前段で探した頂点候補のうち、最も重心に近いものが中心シンボルの内対角点
+// int key_symble_idx=0;
+// int x=i_sqare[0].imvertex[i_vertex_id[0]].x-cx;
+// int y=i_sqare[0].imvertex[i_vertex_id[0]].y-cy;
+// int dmax=x*x+y*y;
+// for(int i=1;i<3;i++){
+// x=i_sqare[i].imvertex[i_vertex_id[i]].x-cx;
+// y=i_sqare[i].imvertex[i_vertex_id[i]].y-cy;
+// final int d=x*x+y*y;
+// if(d<dmax){
+// dmax=d;
+// key_symble_idx=i;
+// }
+// }
+// return key_symble_idx;
+// }
+// public void bindSquare(NyARSquare i_sq1,int i_lv1,NyARSquare i_sq2,int i_lv2)
+// {
+// NyARSquare new_square=new NyARSquare();
+// //4辺の式を計算
+// new_square.line[0].copyFrom(i_sq1.line[(i_lv1)%4]);
+// new_square.line[1].copyFrom(i_sq1.line[(i_lv1+3)%4]);
+// new_square.line[2].copyFrom(i_sq2.line[(i_lv2)%4]);
+// new_square.line[3].copyFrom(i_sq2.line[(i_lv2+3)%4]);
+// //歪み無しの座標系を計算
+// final NyARDoublePoint2d[] l_sqvertex = new_square.sqvertex;
+// final NyARLinear[] l_line = new_square.line;
+// for (int i = 0; i < 4; i++) {
+// final NyARLinear l_line_i = l_line[i];
+// final NyARLinear l_line_2 = l_line[(i + 3) % 4];
+// final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise;
+// if (w1 == 0.0) {
+// return;
+// }
+// l_sqvertex[i].x = (l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1;
+// l_sqvertex[i].y = (l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1;
+//// // 頂点インデクスから頂点座標を得て保存
+//// l_imvertex[i].x = i_xcoord[i_mkvertex[i]];
+//// l_imvertex[i].y = i_ycoord[i_mkvertex[i]];
+// }
+// Graphics g=this.bimg.getGraphics();
+// g.setColor(Color.red);
+// int[] x=new int[4];
+// int[] y=new int[4];
+// for(int i=0;i<4;i++){
+// x[i]=(int)l_sqvertex[i].x;
+// y[i]=(int)l_sqvertex[i].y;
+// }
+// g.drawPolygon(x,y,4);
+// //基準点はVertexをそのまま採用
+// //2個の想定点は座標を逆変換して設定
+// }
+// /**
+// *
+// * @param i_sq
+// * @param o_sq
+// * @return
+// */
+// public boolean margeEdge(NyARSquare[] i_sq,NyARSquare o_sq)
+// {
+// int[] minimum_triangle_vertex=new int[3];
+// int[] minimum_line_vertex=new int[2];
+//
+// //辺の長さが最小になる頂点の組合せを探す
+// getMinimumTriangleVertex(i_sq,minimum_triangle_vertex);
+//
+// //キーシンボルのインデクス番号を得る
+// int key_simble_idx=getKeySymble(i_sq,minimum_triangle_vertex);
+//
+// //エッジシンボルのインデックス番号を決める
+// int symbol_e1_idx=(key_simble_idx+1)%3;
+// int symbol_e2_idx=(key_simble_idx+2)%3;
+//
+// //エッジシンボル間で最短距離を取る頂点ペアを取る
+// //(角度を低くするとエラーが出やすい。対角線との類似性を確認する方法のほうがいい。多分)
+// getMinimumLineVertex(i_sq[symbol_e1_idx].imvertex,i_sq[symbol_e2_idx].imvertex,minimum_line_vertex);
+//
+// //内対角を外対角に変換
+// int lv1=(minimum_line_vertex[0]+2)%4;
+// int lv2=(minimum_line_vertex[1]+2)%4;
+// int kv =(minimum_triangle_vertex[key_simble_idx]+2)%4;
+// //矩形のバインド
+// bindSquare(i_sq[symbol_e1_idx],lv1,i_sq[symbol_e2_idx],lv2);
+//
+//
+// Graphics g=this.bimg.getGraphics();
+// //内対角に緑の点を打つ
+// g.setColor(Color.green);
+// g.fillRect(i_sq[symbol_e1_idx].imvertex[lv1].x-2,i_sq[symbol_e1_idx].imvertex[lv1].y-2,4,4);
+// g.fillRect(i_sq[symbol_e2_idx].imvertex[lv2].x-2,i_sq[symbol_e2_idx].imvertex[lv2].y-2,4,4);
+//// g.fillRect(i_sq[symbol_e2_idx][minimum_line_vertex[1]].x-2,i_sq[symbol_e2_idx][minimum_line_vertex[1]].y-2,4,4);
+//
+//
+// //中央の中心エッジから最も遠い点が
+// //両端のエッジも探す
+//
+//
+//
+//
+//// this.bimg.getGraphics().fillRect(i_sq[edge1_id][vid1_id].x,i_sq[edge1_id][vid1_id].y,5,5);
+//
+// for (int i = 0; i <3; i++) {
+// int[] xp=new int[4];
+// int[] yp=new int[4];
+// for(int i2=0;i2<4;i2++){
+// xp[i2]=i_sq[i].imvertex[i2].x;
+// yp[i2]=i_sq[i].imvertex[i2].y;
+// }
+// this.bimg.getGraphics().setColor(Color.RED);
+// this.bimg.getGraphics().drawPolygon(xp, yp,4);
+// }
+//
+//
+// return false;
+//
+//
+//
+//
+//
+//
+// }
+//
+//
+//
+//
+//}
+
+
+/**
+ * 矩形座標をPCAではなく、頂点座標そのものからSquare位置を計算するクラス
+ *
+ */
+class NyARQRCodeDetector implements INyARSquareDetector
+{
+ LabelingBufferdImage bimg;
+ private static final double VERTEX_FACTOR = 2.0;// 線検出のファクタ
+
+ private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000
+
+ private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70
+
+ private final int _width;
+
+ private final int _height;
+
+ private final NyARLabeling_ARToolKit _labeling;
+
+ private final NyARLabelingImage _limage;
+
+ private final NyARCameraDistortionFactor _dist_factor_ref;
+
+ /**
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。
+ *
+ * @param i_param
+ */
+ public NyARQRCodeDetector(NyARCameraDistortionFactor i_dist_factor_ref, NyARIntSize i_size) throws NyARException
+ {
+ this._width = i_size.w;
+ this._height = i_size.h;
+ this._dist_factor_ref = i_dist_factor_ref;
+ this._labeling = new NyARLabeling_ARToolKit();
+ this._limage = new NyARLabelingImage(this._width, this._height);
+ this._labeling.attachDestination(this._limage);
+
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
+ int number_of_coord = (this._width + this._height) * 2;
+
+ // 輪郭バッファは頂点変換をするので、輪郭バッファの2倍取る。
+ this._max_coord = number_of_coord;
+ this._xcoord = new int[number_of_coord * 2];
+ this._ycoord = new int[number_of_coord * 2];
+ }
+
+ private final int _max_coord;
+
+ private final int[] _xcoord;
+
+ private final int[] _ycoord;
+
+ private void normalizeCoord(int[] i_coord_x, int[] i_coord_y, int i_index, int i_coord_num)
+ {
+ // vertex1を境界にして、後方に配列を連結
+ System.arraycopy(i_coord_x, 1, i_coord_x, i_coord_num, i_index);
+ System.arraycopy(i_coord_y, 1, i_coord_y, i_coord_num, i_index);
+ }
+
+ private final int[] __detectMarker_mkvertex = new int[5];
+
+ /**
+ * ARMarkerInfo2 *arDetectMarker2( ARInt16 *limage, int label_num, int *label_ref,int *warea, double *wpos, int *wclip,int area_max, int area_min, double
+ * factor, int *marker_num ) 関数の代替品 ラベリング情報からマーカー一覧を作成してo_marker_listを更新します。 関数はo_marker_listに重なりを除外したマーカーリストを作成します。
+ *
+ * @param i_raster
+ * 解析する2値ラスタイメージを指定します。
+ * @param o_square_stack
+ * 抽出した正方形候補を格納するリスト
+ * @throws NyARException
+ */
+ public final void detectMarker(NyARBinRaster i_raster, NyARSquareStack o_square_stack) throws NyARException
+ {
+ final INyARLabeling labeling_proc = this._labeling;
+ final NyARLabelingImage limage = this._limage;
+
+ // 初期化
+
+ // マーカーホルダをリセット
+ o_square_stack.clear();
+
+ // ラベリング
+ labeling_proc.labeling(i_raster);
+
+ // ラベル数が0ならここまで
+ final int label_num = limage.getLabelStack().getLength();
+ if (label_num < 1) {
+ return;
+ }
+
+ final NyARLabelingLabelStack stack = limage.getLabelStack();
+ // ラベルを大きい順に整列
+ stack.sortByArea();
+ final NyARLabelingLabel[] labels = stack.getArray();
+
+
+ // デカいラベルを読み飛ばし
+ int i;
+ for (i = 0; i < label_num; i++) {
+ // 検査対象内のラベルサイズになるまで無視
+ if (labels[i].area <= AR_AREA_MAX) {
+ break;
+ }
+ }
+
+ final int xsize = this._width;
+ final int ysize = this._height;
+ final int[] xcoord = this._xcoord;
+ final int[] ycoord = this._ycoord;
+ final int coord_max = this._max_coord;
+ final int[] mkvertex = this.__detectMarker_mkvertex;
+ final int[][] buf = (int[][]) limage.getBufferReader().getBuffer();
+ final int[] indextable = limage.getIndexArray();
+ int coord_num;
+ int label_area;
+ NyARLabelingLabel label_pt;
+ NyARSquareStack wk_stack=new NyARSquareStack(100);
+
+ for (; i < label_num; i++) {
+ label_pt = labels[i];
+ label_area = label_pt.area;
+ // 検査対象サイズよりも小さくなったら終了
+ if (label_area < AR_AREA_MIN) {
+ break;
+ }
+ // クリップ領域が画面の枠に接していれば除外
+ if (label_pt.clip_l == 1 || label_pt.clip_r == xsize - 2) {// if(wclip[i*4+0] == 1 || wclip[i*4+1] ==xsize-2){
+ continue;
+ }
+ if (label_pt.clip_t == 1 || label_pt.clip_b == ysize - 2) {// if( wclip[i*4+2] == 1 || wclip[i*4+3] ==ysize-2){
+ continue;
+ }
+ // 特徴点候補であるかを確認する。
+ if (!hasQrEdgeFeature(buf, indextable, label_pt)) {
+ continue;
+ }
+
+ // 輪郭を取得
+ coord_num = limage.getContour(i, coord_max, xcoord, ycoord);
+ if (coord_num == coord_max) {
+ // 輪郭が大きすぎる。
+ continue;
+ }
+ // 頂点候補のインデクスを取得
+ final int vertex1 = scanVertex(xcoord, ycoord, coord_num);
+
+ // 頂点候補(vertex1)を先頭に並べなおした配列を作成する。
+ normalizeCoord(xcoord, ycoord, vertex1, coord_num);
+
+ // 頂点情報を取得
+ if (!getSquareVertex(xcoord, ycoord, vertex1, coord_num, label_area, mkvertex)) {
+ continue;
+ }
+ NyARSquare square=(NyARSquare)wk_stack.prePush();
+ if(!getSquareLine(mkvertex,xcoord,ycoord,square)){
+ wk_stack.pop();
+ continue;
+ }
+ }
+ bindQrcodeEdge(wk_stack);
+ //エッジ同士の相関関係をしらべる。
+
+ return;
+ }
+ /**
+ *
+ * @param i_sq
+ * @param o_sq
+ * @return
+ */
+ public boolean margeEdge(NyARSquare[] i_sq,NyARSquare o_sq)
+ {
+ NyQrCodeSymbolBinder binder=new NyQrCodeSymbolBinder();
+ binder.bimg=this.bimg;
+ binder.(i_sq, o_sq);
+
+ return false;
+
+
+
+
+ }
+ /**
+ * QRコードのエッジペアを作る
+ * @param i_square_stack
+ */
+ public void bindQrcodeEdge(NyARSquareStack i_square_stack)
+ {
+
+ NyARSquare sq_ptr1,sq_ptr2,sq_ptr3;
+ int number_of_edge=i_square_stack.getLength();
+ if(number_of_edge<3){
+ return;
+ }
+ NyARSquare[] sa=i_square_stack.getArray();
+ for(int i=0;i<number_of_edge;i++)
+ {
+ for(int i2=i+1;i2<number_of_edge;i2++)
+ {
+ sq_ptr2=sa[i2];
+ for(int i3=i2+1;i3<number_of_edge;i3++){
+ sq_ptr3=sa[i3];
+ //3個のエッジの関連性を確認する。
+ margeEdge(sa,null);
+ }
+ //
+ }
+ }
+ }
+ /**
+ * 2つの頂点座標を結ぶ直線から、NyARLinearを計算する。
+ *
+ * @param i_v1
+ * @param i_v2
+ * @param o_line
+ */
+ final private void getLine(NyARDoublePoint2d i_v1, NyARDoublePoint2d i_v2, NyARLinear o_line)
+ {
+ final double x = i_v1.x - i_v2.x;
+ final double y = i_v1.y - i_v2.y;
+ final double x2 = x * x;
+ final double y2 = y * y;
+ final double rise_ = Math.sqrt(x2 / (x2 + y2));
+ o_line.rise = rise_;
+ o_line.run = Math.sqrt(y2 / (x2 + y2));
+ if (x < 0) {
+ if (y < 0) {
+ o_line.rise = -o_line.rise;
+ } else {
+ o_line.rise = -o_line.rise;
+ o_line.run = -o_line.run;
+ }
+ } else {
+ if (y < 0) {
+ o_line.rise = -o_line.rise;
+ o_line.run = -o_line.run;
+ } else {
+ o_line.rise = -o_line.rise;
+ }
+ }
+ o_line.intercept = (i_v1.y + (o_line.run / o_line.rise) * (i_v1.x)) * rise_;
+
+ }
+ private final INyARPca2d _pca=new NyARPca2d_MatrixPCA_O2(100);
+ private final NyARDoubleMatrix22 __getSquareLine_evec=new NyARDoubleMatrix22();
+ private final NyARDoublePoint2d __getSquareLine_mean=new NyARDoublePoint2d();
+ private final NyARDoublePoint2d __getSquareLine_ev=new NyARDoublePoint2d();
+ /**
+ * arGetLine(int x_coord[], int y_coord[], int coord_num,int vertex[], double line[4][3], double v[4][2]) arGetLine2(int x_coord[], int y_coord[], int
+ * coord_num,int vertex[], double line[4][3], double v[4][2], double *dist_factor) の2関数の合成品です。 マーカーのvertex,lineを計算して、結果をo_squareに保管します。
+ * Optimize:STEP[424->391]
+ *
+ * @param i_cparam
+ * @return
+ * @throws NyARException
+ */
+ private boolean getSquareLine(int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord, NyARSquare o_square) throws NyARException
+ {
+ final NyARLinear[] l_line = o_square.line;
+ final NyARCameraDistortionFactor dist_factor=this._dist_factor_ref;
+ final NyARDoubleMatrix22 evec=this.__getSquareLine_evec;
+ final NyARDoublePoint2d mean=this.__getSquareLine_mean;
+ final NyARDoublePoint2d ev=this.__getSquareLine_ev;
+
+
+ for (int i = 0; i < 4; i++) {
+ final double w1 = (double) (i_mkvertex[i + 1] - i_mkvertex[i] + 1) * 0.05 + 0.5;
+ final int st = (int) (i_mkvertex[i] + w1);
+ final int ed = (int) (i_mkvertex[i + 1] - w1);
+ final int n = ed - st + 1;
+ if (n < 2) {
+ // nが2以下でmatrix.PCAを計算することはできないので、エラー
+ return false;
+ }
+ //主成分分析する。
+ this._pca.pcaWithDistortionFactor(i_xcoord, i_ycoord, st, n,dist_factor, evec, ev,mean);
+ final NyARLinear l_line_i = l_line[i];
+ l_line_i.run = evec.m01;// line[i][0] = evec->m[1];
+ l_line_i.rise = -evec.m00;// line[i][1] = -evec->m[0];
+ l_line_i.intercept = -(l_line_i.run * mean.x + l_line_i.rise * mean.y);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);
+ }
+
+ final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;
+ final NyARIntPoint2d[] l_imvertex = o_square.imvertex;
+ for (int i = 0; i < 4; i++) {
+ final NyARLinear l_line_i = l_line[i];
+ final NyARLinear l_line_2 = l_line[(i + 3) % 4];
+ final double w1 = l_line_2.run * l_line_i.rise - l_line_i.run * l_line_2.rise;
+ if (w1 == 0.0) {
+ return false;
+ }
+ l_sqvertex[i].x = (l_line_2.rise * l_line_i.intercept - l_line_i.rise * l_line_2.intercept) / w1;
+ l_sqvertex[i].y = (l_line_i.run * l_line_2.intercept - l_line_2.run * l_line_i.intercept) / w1;
+ // 頂点インデクスから頂点座標を得て保存
+ l_imvertex[i].x = i_xcoord[i_mkvertex[i]];
+ l_imvertex[i].y = i_ycoord[i_mkvertex[i]];
+ }
+ return true;
+ }
+ /**
+ * 辺からの対角線が最長になる点を対角線候補として返す。
+ *
+ * @param i_xcoord
+ * @param i_ycoord
+ * @param i_coord_num
+ * @return
+ */
+ private int scanVertex(int[] i_xcoord, int[] i_ycoord, int i_coord_num)
+ {
+ final int sx = i_xcoord[0];
+ final int sy = i_ycoord[0];
+ int d = 0;
+ int w, x, y;
+ int ret = 0;
+ for (int i = 1; i < i_coord_num; i++) {
+ x = i_xcoord[i] - sx;
+ y = i_ycoord[i] - sy;
+ w = x * x + y * y;
+ if (w > d) {
+ d = w;
+ ret = i;
+ }
+ // ここでうまく終了条件入れられないかな。
+ }
+ return ret;
+ }
+
+ private final NyARVertexCounter __getSquareVertex_wv1 = new NyARVertexCounter();
+
+ private final NyARVertexCounter __getSquareVertex_wv2 = new NyARVertexCounter();
+
+ /**
+ * static int arDetectMarker2_check_square( int area, ARMarkerInfo2 *marker_info2, double factor ) 関数の代替関数 OPTIMIZED STEP [450->415] o_squareに頂点情報をセットします。
+ *
+ * @param i_x_coord
+ * @param i_y_coord
+ * @param i_vertex1_index
+ * @param i_coord_num
+ * @param i_area
+ * @param o_vertex
+ * 要素数はint[4]である事
+ * @return
+ */
+ private boolean getSquareVertex(int[] i_x_coord, int[] i_y_coord, int i_vertex1_index, int i_coord_num, int i_area, int[] o_vertex)
+ {
+ final NyARVertexCounter wv1 = this.__getSquareVertex_wv1;
+ final NyARVertexCounter wv2 = this.__getSquareVertex_wv2;
+ final int end_of_coord = i_vertex1_index + i_coord_num - 1;
+ final int sx = i_x_coord[i_vertex1_index];// sx = marker_info2->x_coord[0];
+ final int sy = i_y_coord[i_vertex1_index];// sy = marker_info2->y_coord[0];
+ int dmax = 0;
+ int v1 = i_vertex1_index;
+ for (int i = 1 + i_vertex1_index; i < end_of_coord; i++) {// for(i=1;i<marker_info2->coord_num-1;i++)
+ // {
+ final int d = (i_x_coord[i] - sx) * (i_x_coord[i] - sx) + (i_y_coord[i] - sy) * (i_y_coord[i] - sy);
+ if (d > dmax) {
+ dmax = d;
+ v1 = i;
+ }
+ }
+ final double thresh = (i_area / 0.75) * 0.01 * VERTEX_FACTOR;
+
+ o_vertex[0] = i_vertex1_index;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v1, thresh)) { // if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,0,v1,thresh,wv1,&wvnum1)<
+ // 0 ) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v1, end_of_coord, thresh)) {// if(get_vertex(marker_info2->x_coord,marker_info2->y_coord,v1,marker_info2->coord_num-1,thresh,wv2,&wvnum2)
+ // < 0) {
+ return false;
+ }
+
+ int v2;
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {// if(wvnum1 == 1 && wvnum2== 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = v1;
+ o_vertex[3] = wv2.vertex[0];
+ } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {// }else if( wvnum1 > 1 && wvnum2== 0) {
+ // 頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。
+ v2 = (v1 - i_vertex1_index) / 2 + i_vertex1_index;
+ if (!wv1.getVertex(i_x_coord, i_y_coord, i_vertex1_index, v2, thresh)) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, v1, thresh)) {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+ o_vertex[1] = wv1.vertex[0];
+ o_vertex[2] = wv2.vertex[0];
+ o_vertex[3] = v1;
+ } else {
+ return false;
+ }
+ } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {
+ // v2 = (v1-i_vertex1_index+ end_of_coord-i_vertex1_index) / 2+i_vertex1_index;
+ v2 = (v1 + end_of_coord) / 2;
+
+ if (!wv1.getVertex(i_x_coord, i_y_coord, v1, v2, thresh)) {
+ return false;
+ }
+ if (!wv2.getVertex(i_x_coord, i_y_coord, v2, end_of_coord, thresh)) {
+ return false;
+ }
+ if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
+ o_vertex[1] = v1;
+ o_vertex[2] = wv1.vertex[0];
+ o_vertex[3] = wv2.vertex[0];
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ o_vertex[4] = end_of_coord;
+ return true;
+ }
+ /**
+ * QRコードのエッジ特徴を持つラベルであるかを調べる
+ * @param buf
+ * @param index_table
+ * @param i_label
+ * @return
+ */
+ private boolean hasQrEdgeFeature(int buf[][], int[] index_table, NyARLabelingLabel i_label)
+ {
+ int tx, bx;
+ int w;
+ int i_label_id = i_label.id;
+ int[] limage_j;
+ final int clip_l = i_label.clip_l;
+ final int clip_b = i_label.clip_b;
+ final int clip_r = i_label.clip_r;
+ final int clip_t = i_label.clip_t;
+
+ tx = bx = 0;
+ // 上接点(→)
+ limage_j = buf[clip_t];
+ for (int i = clip_l; i <= clip_r; i++) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+ w = limage_j[i];
+ if (w > 0 && index_table[w - 1] == i_label_id) {
+ tx = i;
+ break;
+ }
+ }
+ // 下接点(←)
+ limage_j = buf[clip_b];
+ for (int i = clip_r; i >= clip_l; i--) {// for( i = clip[0]; i <=clip[1]; i++, p1++ ) {
+ w = limage_j[i];
+ if (w > 0 && index_table[w - 1] == i_label_id) {
+ bx = i;
+ break;
+ }
+ }
+ final int cx = (clip_l + clip_r) / 2;
+ final int cy = (clip_t + clip_b) / 2;
+ // 横断チェック(中心から線を引いて、101になるかしらべる)
+ if (!checkDiagonalLine(buf, cx, cy, bx, clip_b)) {
+ return false;
+ }
+ if (!checkDiagonalLine(buf, tx, clip_t, cx, cy)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 対角線のパターンを調べる。
+ *
+ * @param buf
+ * @param i_px1
+ * @param i_py1
+ * @param i_px2
+ * @param i_py2
+ * @return
+ */
+ private boolean checkDiagonalLine(int[][] buf, int i_px1, int i_py1, int i_px2, int i_py2)
+ {
+ int sub_y = i_py2 - i_py1;
+ int sub_x = i_px2 - i_px1;
+ // 黒
+ int i = 0;
+ for (; i < sub_y; i++) {
+ int yp = i_py1 + i;
+ int xp = i_px1 + i * sub_x / sub_y;
+ if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+ break;
+ }
+
+ }
+ if (i == sub_y) {
+ return false;
+ }
+ // 白
+ for (; i < sub_y; i++) {
+ int yp = i_py1 + i;
+ int xp = i_px1 + i * sub_x / sub_y;
+ if (buf[yp][xp] != 0 && buf[yp][xp-1] != 0 && buf[yp][xp+1] != 0) {
+ break;
+ }
+
+ }
+ if (i == sub_y) {
+ return false;
+ }
+ // 黒
+ for (; i < sub_y; i++) {
+ int yp = i_py1 + i;
+ int xp = i_px1 + i * sub_x / sub_y;
+ if (buf[yp][xp] == 0 && buf[yp][xp-1] == 0 && buf[yp][xp+1] == 0) {
+ break;
+ }
+
+ }
+ if (i != sub_y) {
+ return false;
+ }
+ // 端まで到達したらOK
+ return true;
+ }
+
+}
+
+
+public class LabelingCamera extends Frame implements JmfCaptureListener
+{
+ private final String camera_file = "../Data/camera_para.dat";
+
+ private JmfNyARRaster_RGB _raster;
+
+ private JmfCameraCapture capture;
+ private NyARParam ap;
+ public LabelingCamera() throws NyARException, NyARException
+ {
+ setBounds(0, 0, 640 + 64, 720 + 64);
+ // キャプチャの準備
+ capture = new JmfCameraCapture(320, 240, 30f, JmfCameraCapture.PIXEL_FORMAT_RGB);
+ capture.setCaptureListener(this);
+
+ // キャプチャイメージ用のラスタを準備
+ this._raster = new JmfNyARRaster_RGB(320, 240);
+
+ // AR用カメラパラメタファイルをロード
+ ap = new NyARParam();
+ ap.loadARParamFromFile(camera_file);
+ ap.changeScreenSize(320, 240);
+
+
+ }
+
+ // そのラベルが特徴点候補か返す。
+
+ private NyARBinRaster _binraster1 = new NyARBinRaster(320, 240);
+
+ private NyARGrayscaleRaster _gsraster1 = new NyARGrayscaleRaster(320, 240);
+
+ private NyARLabelingImage _limage = new NyARLabelingImage(320, 240);
+
+ private LabelingBufferdImage _bimg = new LabelingBufferdImage(320, 240);
+
+ private NyARRasterFilter_ARToolkitThreshold filter_gs2bin;
+
+ public void onUpdateBuffer(Buffer i_buffer)
+ {
+ NyARRasterFilter_AreaAverage gs2bin=new NyARRasterFilter_AreaAverage();
+
+ try {
+ // キャプチャしたバッファをラスタにセット
+ _raster.setBuffer(i_buffer);
+
+ Graphics g = getGraphics();
+ // キャプチャ画像
+ BufferToImage b2i = new BufferToImage((VideoFormat) i_buffer.getFormat());
+ Image img = b2i.createImage(i_buffer);
+ this.getGraphics().drawImage(img, 32, 32, this);
+
+ // 画像1
+ INyARRasterFilter_RgbToGs filter_rgb2gs = new NyARRasterFilter_RgbAve();
+ filter_rgb2gs.doFilter(_raster, _gsraster1);
+ this._bimg.drawImage(this._gsraster1);
+ this.getGraphics().drawImage(this._bimg, 32 + 320, 32, 320 + 320 + 32, 240 + 32, 0, 240, 320, 0, this);
+
+
+ // 画像2
+ gs2bin.doFilter(_gsraster1, _binraster1);
+ this._bimg.drawImage(_binraster1);
+ this.getGraphics().drawImage(this._bimg, 32, 32 + 240, 320 + 32, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+ // 画像3
+ NyARLabelingImage limage = new NyARLabelingImage(320, 240);
+ NyARLabeling_ARToolKit labeling = new NyARLabeling_ARToolKit();
+ labeling.attachDestination(limage);
+ labeling.labeling(_binraster1);
+ this._bimg.drawImage(this._gsraster1);
+ NyARLabelingLabel[] labels = limage.getLabelStack().getArray();
+
+ NyARSquareStack stack = new NyARSquareStack(100);
+ NyARQRCodeDetector detect = new NyARQRCodeDetector(ap.getDistortionFactor(), new NyARIntSize(320,240));
+ detect.bimg=this._bimg;
+
+ detect.detectMarker(_binraster1, stack);
+ for (int i = 0; i < stack.getLength(); i++) {
+ NyARSquare[] square_ptr = (NyARSquare[]) stack.getArray();
+ int[] xp=new int[4];
+ int[] yp=new int[4];
+ for(int i2=0;i2<4;i2++){
+ xp[i2]=square_ptr[i].imvertex[i2].x;
+ yp[i2]=square_ptr[i].imvertex[i2].y;
+ }
+ this._bimg.getGraphics().setColor(Color.RED);
+ this._bimg.getGraphics().drawPolygon(xp, yp,2);
+ }
+ this.getGraphics().drawImage(this._bimg, 32 + 320, 32 + 240, 320 + 32 + 320, 240 + 32 + 240, 0, 240, 320, 0, this);
+
+ // 画像3
+ // threshold.debugDrawHistgramMap(_workraster, _workraster2);
+ // this._bimg2.setImage(this._workraster2);
+ // this.getGraphics().drawImage(this._bimg2, 32+320, 32+240,320+32+320,240+32+240,0,240,320,0, this);
+
+ // 画像4
+ // NyARRasterThresholdAnalyzer_SlidePTile threshold=new NyARRasterThresholdAnalyzer_SlidePTile(15);
+ // threshold.analyzeRaster(_gsraster1);
+ // filter_gs2bin=new NyARRasterFilter_AreaAverage();
+ // filter_gs2bin.doFilter(_gsraster1, _binraster1);
+ // this._bimg.drawImage(_binraster1);
+
+ // NyARRasterDetector_QrCodeEdge detector=new NyARRasterDetector_QrCodeEdge(10000);
+ // detector.analyzeRaster(_binraster1);
+
+ // this._bimg.overlayData(detector.geResult());
+
+ // this.getGraphics().drawImage(this._bimg, 32, 32+480,320+32,480+32+240,0,240,320,0, this);
+ // 画像5
+
+ /*
+ * threshold2.debugDrawHistgramMap(_workraster, _workraster2); this._bimg2.drawImage(this._workraster2); this.getGraphics().drawImage(this._bimg2,
+ * 32+320, 32+480,320+32+320,480+32+240,0,240,320,0, this);
+ */
+
+ // this.getGraphics().drawImage(this._bimg, 32, 32, this);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private INyARLabeling labelingFactory(int i_idx)
+ {
+ // switch(i_idx){
+ // case 0:{NyARLabeling_ARToolKit l=new NyARLabeling_ARToolKit();l.setThresh(4);return l;}
+ // case 1:{return new NyLineLabeling();}
+ // }
+ return null;
+
+ }
+
+ private void startCapture()
+ {
+ try {
+ capture.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ LabelingCamera mainwin = new LabelingCamera();
+ mainwin.setVisible(true);
+ mainwin.startCapture();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
--- /dev/null
+/* このソースは実験用のソースです。\r
+ * 動いたり動かなかったりします。\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+import java.awt.*;\r
+import java.awt.event.WindowAdapter;\r
+import java.awt.event.WindowEvent;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster_BGRA;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilterBuilder_RgbToBin;\r
+import jp.nyatla.nyartoolkit.utils.j2se.*;\r
+\r
+\r
+\r
+public class LabelingTest extends Frame\r
+{\r
+ private final String data_file = "../Data/320x240ABGR.raw";\r
+\r
+ final int W=10;\r
+ final int H=10;\r
+ public void drawImage() throws Exception\r
+ {\r
+ File f = new File(data_file);\r
+ FileInputStream fs = new FileInputStream(data_file);\r
+ byte[] buf = new byte[(int) f.length()];\r
+ fs.read(buf);\r
+ NyARRgbRaster_BGRA ra = NyARRgbRaster_BGRA.wrap(buf, W, H);\r
+ // 二値化\r
+ NyARRasterFilterBuilder_RgbToBin filter = new NyARRasterFilterBuilder_RgbToBin(110, ra.getBufferReader().getBufferType());\r
+ NyARBinRaster bin = new NyARBinRaster(W,240);\r
+ filter.doFilter(ra, bin);\r
+ int[] t = (int[]) bin.getBufferReader().getBuffer();\r
+ int[] s = {\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+\r
+ 1,0,0,0,0,1,0,1,1,1,\r
+ 1,0,1,1,0,1,0,1,1,1,\r
+ 1,1,1,1,1,0,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1,\r
+ 1,1,1,1,1,1,1,1,1,1, 0};\r
+ System.arraycopy(s, 0, t, 0, 10*10);\r
+ NyARRasterImageIO sink = new NyARRasterImageIO(W, H);\r
+ RleImage rle = new RleImage(bin.getWidth(),bin.getHeight());\r
+ RleLabelingTable table=createRelTable(rle,bin,sink);\r
+ for(int i=0;;i++){\r
+ int nof=i%table.number_of_fragment;\r
+ if(table._fragment_area[nof]==0){\r
+ continue;\r
+ }\r
+ drawLabelingImage(nof,rle,table,bin,sink);\r
+ Graphics g;\r
+ g=this.getGraphics();\r
+ g.drawImage(sink, 100, 100,100,100, this);\r
+ Thread.sleep(500);\r
+ }\r
+ }\r
+ public void drawLabelingImage(int id,RleImage rle, RleLabelingTable i_table,NyARBinRaster i_source,NyARRasterImageIO i_img)\r
+ {\r
+// RleImage rle = new RleImage(i_source.getWidth(),i_source.getHeight());\r
+// i_table.labeling(rle,0,10);\r
+ int p=0;\r
+ for(int i=0;i<H;i++){\r
+ for(int i2=0;i2<W;i2++){\r
+ i_img.setRGB(i2,i,0xffffff);\r
+ }\r
+ for(int i2=0;i2<rle.row_length[i];i2++){\r
+ for(int i3=rle.rle_img_l[rle.row_index[i]+i2];i3<rle.rle_img_r[rle.row_index[i]+i2];i3++)\r
+ {\r
+ int c=0x0000ff;\r
+ int tid=i_table._fragment_id[i_table.rle_img_id[p]];\r
+ if(tid==id){\r
+ c=0x00ff00;\r
+ }\r
+ i_img.setRGB(i3,i,c);\r
+ }\r
+ p++;\r
+ }\r
+ }\r
+\r
+ i_img.setRGB(i_table._flagment_entry_x[id],i_table._flagment_entry_y[id],0xff0000);\r
+// i_img.setRGB(i_table._flagment_entry_x[id]+1,i_table._flagment_entry_y[id],0xff0000);\r
+// i_img.setRGB(i_table._flagment_entry_x[id],i_table._flagment_entry_y[id]+1,0xff0000);\r
+// i_img.setRGB(i_table._flagment_entry_x[id]+1,i_table._flagment_entry_y[id]+1,0xff0000);\r
+ }\r
+ \r
+ public RleLabelingTable createRelTable(RleImage rle,NyARBinRaster i_source,NyARRasterImageIO i_img)\r
+ {\r
+ // RELイメージの作成\r
+ rle.toRel(i_source);\r
+ // 1行目のテーブル登録\r
+ RleLabelingTable table = new RleLabelingTable(10000);\r
+ table.labeling(rle,0,H);\r
+ return table;\r
+ }\r
+\r
+ public LabelingTest() throws NyARException\r
+ {\r
+ this.addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ try {\r
+ LabelingTest app = new LabelingTest();\r
+ app.setVisible(true);\r
+ app.setBounds(0, 0, 640, 480);\r
+ app.drawImage();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ class RleImage\r
+ {\r
+ int _width;\r
+\r
+ int _height;\r
+\r
+ // RELデータ\r
+ short[] rle_img_l;// RELのフラグメント左\r
+\r
+ short[] rle_img_r;// RELのフラグメント右\r
+\r
+ // Rowデータ\r
+ int[] row_index;\r
+\r
+ short[] row_length;\r
+\r
+ int rle_buf_size;\r
+\r
+ public RleImage(int i_width, int i_height)\r
+ {\r
+ final int size = i_width * i_height / 2;\r
+ // 1/2に圧縮できることを想定。\r
+ this.rle_img_l = new short[size]; // RELのフラグメント長\r
+ this.rle_img_r = new short[size]; // RELの開始位置\r
+ this.rle_buf_size = size;\r
+\r
+ this.row_index = new int[i_height];\r
+ this.row_length = new short[i_height];\r
+ this._width = i_width;\r
+ this._height = i_height;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * binラスタからRELに変換する\r
+ * \r
+ * @param i_bin_raster\r
+ */\r
+ public void toRel(NyARBinRaster i_bin_raster)\r
+ {\r
+ final int width = this._width;\r
+ final int height = this._height;\r
+ int[] in_buf = (int[]) i_bin_raster.getBufferReader().getBuffer();\r
+\r
+ short current = 0;\r
+ short r = -1;\r
+ for (int y = 0; y < height; y++) {\r
+ this.row_index[y] = current;\r
+ // 行確定開始\r
+ int row_index = y * width;\r
+ int x = row_index;\r
+ final int right_edge = (y + 1) * width - 1;\r
+ while (x < right_edge) {\r
+ // 暗点(0)スキャン\r
+ if (in_buf[x] != 0) {\r
+ x++;\r
+ continue;\r
+ }\r
+ // 暗点発見→暗点長を調べる\r
+ r = (short) (x - row_index);\r
+ this.rle_img_l[current] = r;\r
+ r++;// 暗点+1\r
+ x++;\r
+ while (x < right_edge) {\r
+ if (in_buf[x] != 0) {\r
+ // 明点(1)→暗点(0)配列終了>登録\r
+ this.rle_img_r[current] = r;\r
+ current++;\r
+ x++;// 次点の確認。\r
+ r = -1;// 右端の位置を0に。\r
+ break;\r
+ } else {\r
+ // 暗点(0)長追加\r
+ r++;\r
+ x++;\r
+ }\r
+ }\r
+ }\r
+ // 最後の1点だけ判定方法が少し違うの。\r
+ if (in_buf[x] != 0) {\r
+ // 明点→rカウント中なら暗点配列終了>登録\r
+ if (r >= 0) {\r
+ this.rle_img_r[current] = r;\r
+ current++;\r
+ }\r
+ } else {\r
+ // 暗点→カウント中でなければl1で追加\r
+ if (r >= 0) {\r
+ this.rle_img_r[current] = (short) (x + 1);\r
+ } else {\r
+ // 最後の1点の場合\r
+ this.rle_img_l[current] = (short) (width - 1);\r
+ this.rle_img_r[current] = (short) (width);\r
+ }\r
+ current++;\r
+ }\r
+ // 行確定\r
+ this.row_length[y] = (short) (current - this.row_index[y]);\r
+ }\r
+ }\r
+\r
+ public void fromRel(NyARBinRaster i_bin_raster)\r
+ {\r
+\r
+ }\r
+ }\r
+\r
+ // RleImageをラベリングする。\r
+ class RleLabelingTable\r
+ {\r
+ short[] rle_img_id;\r
+\r
+ short[] _fragment_id; // フラグメントラベルのインデクス\r
+\r
+ int[] _fragment_area; // フラグメントラベルの領域数\r
+\r
+ int[] _fragment_pos_x; // フラグメントラベルの位置\r
+\r
+ int[] _fragment_pos_y; // フラグメントラベルの位置\r
+\r
+ short[] _flagment_entry_x; // フラグメントラベルの位置\r
+\r
+ short[] _flagment_entry_y; // フラグメントラベルの位置\r
+\r
+ short number_of_fragment; // 現在のフラグメントの数\r
+\r
+ public RleLabelingTable(int i_max_fragment)\r
+ {\r
+ this.rle_img_id = new short[i_max_fragment];\r
+ this._fragment_id = new short[i_max_fragment];\r
+ this._fragment_area = new int[i_max_fragment];\r
+ this._fragment_pos_x = new int[i_max_fragment];\r
+ this._fragment_pos_y = new int[i_max_fragment];\r
+ this._flagment_entry_x = new short[i_max_fragment];\r
+ this._flagment_entry_y = new short[i_max_fragment];\r
+ }\r
+\r
+ private void addFragment(RleImage i_rel_img, short i_nof, int i_row_index, int i_rel_index)\r
+ {\r
+ this.rle_img_id[i_rel_index] = i_nof;// REL毎の固有ID\r
+ this._fragment_id[i_nof] = i_nof;\r
+ this._flagment_entry_x[i_nof] = i_rel_img.rle_img_l[i_rel_index];\r
+ this._flagment_entry_y[i_nof] = (short) i_row_index;\r
+ this._fragment_area[i_nof] = i_rel_img.rle_img_r[i_rel_index] - i_rel_img.rle_img_l[i_rel_index];\r
+ return;\r
+ }\r
+\r
+\r
+\r
+ // 指定した行のフラグメントをマージします。\r
+ public void labeling(RleImage i_rel_img, int i_top, int i_bottom)\r
+ {\r
+ short[] rle_l = i_rel_img.rle_img_l;\r
+ short[] rle_r = i_rel_img.rle_img_r;\r
+ short nof = this.number_of_fragment;\r
+ // 初段登録\r
+ int index = i_rel_img.row_index[i_top];\r
+ int eol = i_rel_img.row_length[i_top];\r
+ for (int i = index; i < index + eol; i++) {\r
+ // フラグメントID=フラグメント初期値、POS=Y値、RELインデクス=行\r
+ addFragment(i_rel_img, nof, i_top, i);\r
+ nof++;\r
+ // nofの最大値チェック\r
+ }\r
+ // 次段結合\r
+ for (int y = i_top+1; y < i_bottom; y++) {\r
+ int index_prev = i_rel_img.row_index[y - 1];\r
+ int eol_prev = index_prev + i_rel_img.row_length[y - 1];\r
+ index = i_rel_img.row_index[y];\r
+ eol = index + i_rel_img.row_length[y];\r
+\r
+ SCAN_CUR:for (int i = index; i < eol; i++) {\r
+ // index_prev,len_prevの位置を調整する\r
+ short id = -1;\r
+ //チェックすべきprevがあれば確認\r
+ SCAN_PREV: while (index_prev < eol_prev) {\r
+ if (rle_l[i] - rle_r[index_prev] > 0) {// 0なら8方位ラベリング\r
+ // prevがcurの左方にある→次のフラグメントを探索\r
+ index_prev++;\r
+ continue;\r
+ } else if (rle_l[index_prev] - rle_r[i] > 0) {// 0なら8方位ラベリングになる\r
+ // prevがcur右方にある→独立フラグメント\r
+ addFragment(i_rel_img, nof, y, i);\r
+ nof++;\r
+ // 次のindexをしらべる\r
+ continue SCAN_CUR;\r
+ }\r
+ // 結合対象->prevのIDをコピーして、対象フラグメントの情報を更新\r
+ id = this._fragment_id[this.rle_img_id[index_prev]];\r
+ this.rle_img_id[i] = id;\r
+ this._fragment_area[id] += (rle_r[i] - rle_l[i]);\r
+ // エントリポイントの情報をコピー\r
+ this._flagment_entry_x[id] = this._flagment_entry_x[this.rle_img_id[index_prev]];\r
+ this._flagment_entry_y[id] = this._flagment_entry_y[this.rle_img_id[index_prev]];\r
+ //多重リンクの確認\r
+\r
+ index_prev++;\r
+ while (index_prev < eol_prev) {\r
+ if (rle_l[i] - rle_r[index_prev] > 0) {// 0なら8方位ラベリング\r
+ // prevがcurの左方にある→prevはcurに連結していない。\r
+ break SCAN_PREV;\r
+ } else if (rle_l[index_prev] - rle_r[i] > 0) {// 0なら8方位ラベリングになる\r
+ // prevがcurの右方にある→prevはcurに連結していない。\r
+ index_prev--;\r
+ continue SCAN_CUR;\r
+ }\r
+ // prevとcurは連結している。\r
+ final short prev_id = this.rle_img_id[index_prev];\r
+ if (id != prev_id) {\r
+ this._fragment_area[id] += this._fragment_area[prev_id];\r
+ this._fragment_area[prev_id] = 0;\r
+ // 結合対象->現在のidをインデクスにセット\r
+ this._fragment_id[prev_id]=id;\r
+ // エントリポイントを訂正\r
+ if (this._flagment_entry_y[id] > this._flagment_entry_y[prev_id]) {\r
+ // 現在のエントリポイントの方が下にある。(何もしない)\r
+ }\r
+ if (this._flagment_entry_y[id] < this._flagment_entry_y[prev_id]) {\r
+ // 現在のエントリポイントの方が上にある。(エントリポイントの交換)\r
+ this._flagment_entry_y[id] = this._flagment_entry_y[prev_id];\r
+ this._flagment_entry_x[id] = this._flagment_entry_x[prev_id];\r
+ } else {\r
+ // 水平方向で小さい方がエントリポイント。\r
+ if (this._flagment_entry_x[id] > this._flagment_entry_x[prev_id]) {\r
+ this._flagment_entry_y[id] = this._flagment_entry_y[prev_id];\r
+ this._flagment_entry_x[id] = this._flagment_entry_x[prev_id];\r
+ }\r
+ }\r
+ }\r
+ index_prev++;\r
+ }\r
+ index_prev--;\r
+ break;\r
+ }\r
+ // curにidが割り当てられたかを確認\r
+ // 右端独立フラグメントを追加\r
+ if (id < 0) {\r
+ addFragment(i_rel_img, nof, y, i);\r
+ nof++;\r
+ }\r
+\r
+ }\r
+ }\r
+ // フラグメントの数を更新\r
+ this.number_of_fragment = nof;\r
+ }\r
+ }\r
+}\r
+\r
+// REL圧縮配列を作成\r
+// REL結合\r
+// 面積計算\r
+// 参照インデクス化\r
+// ラベルイメージ化\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * The NyARToolkit is Java version ARToolkit class library.\r
+ * Copyright (C)2008 R.Iizuka\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this framework; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.types.matrix.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+\r
+\r
+class NyARDoubleLine2d\r
+{\r
+ double x,y;\r
+ void set(NyARDoublePoint2d i_point_a,NyARDoublePoint2d i_point_b)\r
+ {\r
+ this.x=i_point_a.x-i_point_b.x;\r
+ this.y=i_point_a.y-i_point_b.y;\r
+ return;\r
+ }\r
+ void add(NyARDoubleLine2d i_param,NyARDoubleLine2d o_result)\r
+ {\r
+ o_result.x=this.x+i_param.x;\r
+ o_result.y=this.y+i_param.y;\r
+ return;\r
+ }\r
+ void sum(NyARDoubleLine2d i_param,NyARDoubleLine2d o_result)\r
+ {\r
+ o_result.x=this.x-i_param.x;\r
+ o_result.y=this.y-i_param.y;\r
+ return;\r
+ }\r
+ /**\r
+ * i_paramとの外積を計算する。\r
+ * @param i_param\r
+ * @return\r
+ */\r
+ double cross(NyARDoubleLine2d i_param)\r
+ {\r
+ return this.x*i_param.y-this.y*i_param.x;\r
+ }\r
+ /**\r
+ * i_paramとの内積を計算する\r
+ * @param i_param\r
+ * @return\r
+ */\r
+ double dot(NyARDoubleLine2d i_param)\r
+ {\r
+ return this.x*i_param.x+this.y*i_param.y;\r
+ }\r
+ /**\r
+ * このベクトルの絶対値を計算する\r
+ * @param i_param\r
+ * @return\r
+ */\r
+ double dist()\r
+ {\r
+ return Math.sqrt(this.x*this.x+this.y*this.y);\r
+ }\r
+ \r
+ \r
+}\r
+\r
+\r
+class LineParam\r
+{\r
+ public double a;\r
+ public double b;\r
+ public static LineParam[] createArray(int i_length)\r
+ {\r
+ LineParam[] result=new LineParam[i_length];\r
+ for(int i=result.length-1;i>=0;i--){\r
+ result[i]=new LineParam();\r
+ }\r
+ return result;\r
+ }\r
+}\r
+\r
+class Complex\r
+{\r
+ public double i;\r
+ public double r;\r
+ public Complex()\r
+ {\r
+ }\r
+ public Complex(double i_r,double i_i)\r
+ {\r
+ this.r=i_r;\r
+ this.i=i_i;\r
+ }\r
+ public void add(Complex i_v)\r
+ {\r
+ this.r+=i_v.r;\r
+ this.i+=i_v.i;\r
+ }\r
+ public void sub(Complex i_v)\r
+ {\r
+ this.r-=i_v.r;\r
+ this.i-=i_v.i;\r
+ }\r
+ public void sub(Complex i_v1,Complex i_v2)\r
+ {\r
+ this.r=i_v1.r-i_v2.r;\r
+ this.i=i_v1.i-i_v2.i;\r
+ }\r
+ \r
+ public void mul(Complex i_v)\r
+ {\r
+ double r,i;\r
+ r=this.r;\r
+ i=this.i;\r
+ final double d2=Math.sqrt(r*r+i*i);\r
+ final double s2=Math.acos(r/d2);\r
+ r=i_v.r;\r
+ i=i_v.i;\r
+ final double d1=Math.sqrt(r*r+i*i);\r
+ final double s1=Math.acos(r/d1);\r
+ \r
+ this.r=d1*d2*Math.cos(s2+s1);\r
+ this.i=d1*d2*Math.sin(s2+s1);\r
+ return;\r
+ }\r
+ public void div(Complex i_v)\r
+ {\r
+ double r,i;\r
+ r=this.r;\r
+ i=this.i;\r
+ final double d2=Math.sqrt(r*r+i*i);\r
+ final double s2=Math.acos(r/d2);\r
+ r=i_v.r;\r
+ i=i_v.i;\r
+ final double d1=Math.sqrt(r*r+i*i);\r
+ final double s1=Math.acos(r/d1);\r
+ \r
+ this.r=d2/d1*Math.cos(s2/s1);\r
+ this.i=d2/d1*Math.sin(s2/s1);\r
+ return;\r
+ }\r
+ public void pow(Complex i_v,double i_base)\r
+ {\r
+ double r,i;\r
+ r=i_v.r;\r
+ i=i_v.i;\r
+ double d=Math.sqrt(r*r+i*i);\r
+ final double s=Math.acos(r/d)*i_base;\r
+ d=Math.pow(d,i_base);\r
+ this.r=d*Math.cos(s);\r
+ this.i=d*Math.sin(s);\r
+ }\r
+ public void sqrt(Complex i_v)\r
+ {\r
+ double r,i;\r
+ r=i_v.r;\r
+ i=i_v.i;\r
+ double d=Math.sqrt(r*r+i*i);\r
+ final double s=Math.acos(r/d)*0.5;\r
+ d=Math.sqrt(d);\r
+ this.r=d*Math.cos(s);\r
+ this.i=d*Math.sin(s);\r
+ }\r
+ public double dist()\r
+ {\r
+ return Math.sqrt(this.r*this.r+this.i*this.i);\r
+ }\r
+ \r
+}\r
+\r
+\r
+/**\r
+ * 24ビットカラーのマーカーを保持するために使うクラスです。 このクラスは、ARToolkitのパターンと、ラスタから取得したパターンを保持します。\r
+ * 演算順序を含む最適化をしたもの\r
+ * \r
+ */\r
+public class NyARColorPatt_DiagonalRatio implements INyARColorPatt\r
+{\r
+ private int[] _patdata;\r
+ private NyARBufferReader _buf_reader;\r
+ private NyARRgbPixelReader_INT1D_X8R8G8B8_32 _pixelreader;\r
+ private NyARIntSize _size;\r
+ \r
+ public final int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+ \r
+ public final int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+ \r
+ public final NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ \r
+ public final INyARBufferReader getBufferReader()\r
+ {\r
+ return this._buf_reader;\r
+ }\r
+ \r
+ public final INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._pixelreader;\r
+ }\r
+ NyARDoubleMatrix44 _invmat=new NyARDoubleMatrix44();\r
+ /**\r
+ * @param i_width\r
+ * @param i_height\r
+ */\r
+ public NyARColorPatt_DiagonalRatio(int i_model)\r
+ {\r
+ int resolution=(1<<i_model)+1;\r
+ this._size=new NyARIntSize(resolution,resolution);\r
+ this._patdata = new int[resolution*resolution];\r
+ this._buf_reader=new NyARBufferReader(this._patdata,NyARBufferReader.BUFFERFORMAT_INT1D_X8R8G8B8_32);\r
+ this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);\r
+ \r
+ this._vertex_map=NyARDoublePoint2d.create2dArray(this._size.h,this._size.w);\r
+\r
+ return;\r
+ } \r
+ public NyARDoublePoint2d[][] _vertex_map;\r
+ public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square)throws NyARException\r
+ {\r
+ NyARDoublePoint2d center=new NyARDoublePoint2d();\r
+ //中心を取得\r
+ solvCrossPoint(i_square.sqvertex[0],i_square.sqvertex[2],i_square.sqvertex[1],i_square.sqvertex[3],center);\r
+ \r
+ int[] rgb_tmp=new int[3];\r
+ INyARRgbPixelReader reader=image.getRgbPixelReader();\r
+ //頂点マトリクスの計算(2=2分割,3=4分割,4=8分割)\r
+ NyARDoublePoint2d[][] vertex_map=this._vertex_map;\r
+ solvLinePointArray(center,this._size.h-1,i_square.sqvertex,vertex_map);\r
+ for(int i=0;i<this._size.h;i++){\r
+ for(int i2=0;i2<this._size.w;i2++){\r
+ if(vertex_map[i][i2].x>320||vertex_map[i][i2].y>240||vertex_map[i][i2].x<0||vertex_map[i][i2].y<0)\r
+ {\r
+ //System.out.println(vertex_map[i][i2].x+","+vertex_map[i][i2].y);\r
+ this._patdata[i2+i*this._size.w]=0;\r
+ continue;\r
+ }\r
+ reader.getPixel((int)vertex_map[i][i2].x,(int)vertex_map[i][i2].y,rgb_tmp);\r
+ this._patdata[i2+i*this._size.w]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|rgb_tmp[2]; \r
+ } \r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * 直線をscaleで2^n分割した配列を計算する。\r
+ * @param i_p1\r
+ * @param i_p2\r
+ * @param o_param\r
+ * @return\r
+ */\r
+ private void solvLinePointArray4(NyARDoublePoint2d i_center,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+ {\r
+ //分割直線の計算(2=2分割,3=4分割,4=8分割)\r
+ //中心コピー\r
+ o_result[0][0].setValue(i_center);\r
+ \r
+ \r
+ //[0]->[1]のベクトルを計算\r
+ NyARDoublePoint2d vec01=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec12=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec03=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec32=new NyARDoublePoint2d();\r
+ vec01.vecSub(i_vertex[1],i_vertex[0]);\r
+ vec12.vecSub(i_vertex[2],i_vertex[1]);\r
+ vec03.vecSub(i_vertex[3],i_vertex[0]);\r
+ vec32.vecSub(i_vertex[2],i_vertex[3]);\r
+\r
+ //中心点から[0]->[1]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec01_ep=new NyARDoublePoint2d();\r
+ vec01_ep.vecAdd(vec01,i_center);\r
+ //中心点から[3]->[2]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec32_ep=new NyARDoublePoint2d();\r
+ vec32_ep.vecAdd(vec32,i_center); \r
+ //平均値\r
+ NyARDoublePoint2d cx_e=new NyARDoublePoint2d();\r
+ cx_e.x=(vec01_ep.x+vec32_ep.x)/2;\r
+ cx_e.y=(vec01_ep.y+vec32_ep.y)/2;\r
+ \r
+ //ベクトル[1]->[2]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e,i_vertex[1],i_vertex[2],o_result[1][2]);\r
+ //ベクトル[3]->[0]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e,i_vertex[3],i_vertex[0],o_result[1][0]);\r
+ \r
+\r
+ \r
+ //中心点から[1]->[2]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec12_ep=new NyARDoublePoint2d();\r
+ vec12_ep.vecAdd(vec12,i_center);\r
+ //中心点から[0]->[3]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec03_ep=new NyARDoublePoint2d();\r
+ vec03_ep.vecAdd(vec03,i_center); \r
+ //平均値\r
+ NyARDoublePoint2d cx_e2=new NyARDoublePoint2d();\r
+ cx_e2.x=(vec12_ep.x+vec03_ep.x)/2;\r
+ cx_e2.y=(vec12_ep.y+vec03_ep.y)/2;\r
+ \r
+ //cx_e2とベクトル[0]->[1]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e2,i_vertex[0],i_vertex[1],o_result[0][1]);\r
+ //ベクトル[3]->[2]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e2,i_vertex[3],i_vertex[2],o_result[2][1]);\r
+ \r
+ \r
+ \r
+ \r
+ return;\r
+ }\r
+ private void solvLinePointArray(NyARDoublePoint2d i_center,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+ {\r
+ //中心コピー\r
+ o_result[0][0].setValue(i_center);\r
+\r
+ //[0]+[1]+[c]\r
+ NyARDoublePoint2d vt=new NyARDoublePoint2d();\r
+ vt.x=(i_vertex[0].x+i_vertex[1].x)/2;\r
+ vt.y=(i_vertex[0].y+i_vertex[1].y)/2;\r
+ //[2]+[3]+[c]\r
+ NyARDoublePoint2d vb=new NyARDoublePoint2d();\r
+ vb.x=(i_vertex[2].x+i_vertex[3].x)/2;\r
+ vb.y=(i_vertex[2].y+i_vertex[3].y)/2;\r
+ \r
+ vt.vecSub(vb);\r
+ vt.vecAdd(i_center);\r
+\r
+ //[0][1]->[2][3]ベクトル\r
+ solvCrossPoint(vt,i_center,i_vertex[0],i_vertex[1],o_result[1][2]);\r
+ //[0][1]->[2][3]ベクトル:v[3][0]\r
+ solvCrossPoint(vt,i_center,i_vertex[3],i_vertex[2],o_result[1][0]);\r
+\r
+ \r
+ \r
+/* \r
+ \r
+ //[0]->[1]のベクトルを計算\r
+ NyARDoublePoint2d vec01=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec12=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec03=new NyARDoublePoint2d();\r
+ NyARDoublePoint2d vec32=new NyARDoublePoint2d();\r
+ vec01.vecSub(i_vertex[1],i_vertex[0]);\r
+ vec12.vecSub(i_vertex[2],i_vertex[1]);\r
+ vec03.vecSub(i_vertex[3],i_vertex[0]);\r
+ vec32.vecSub(i_vertex[2],i_vertex[3]);\r
+\r
+ //中心点から[0]->[1]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec01_ep=new NyARDoublePoint2d();\r
+ vec01_ep.vecSum(vec01,i_center);\r
+ //中心点から[3]->[2]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec32_ep=new NyARDoublePoint2d();\r
+ vec32_ep.vecSum(vec32,i_center); \r
+ //平均値\r
+ NyARDoublePoint2d cx_e=new NyARDoublePoint2d();\r
+ cx_e.x=(vec01_ep.x+vec32_ep.x)/2;\r
+ cx_e.y=(vec01_ep.y+vec32_ep.y)/2;\r
+ \r
+ //ベクトル[1]->[2]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e,i_vertex[1],i_vertex[2],o_result[1][2]);\r
+ //ベクトル[3]->[0]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e,i_vertex[3],i_vertex[0],o_result[1][0]);\r
+ \r
+\r
+ \r
+ //中心点から[1]->[2]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec12_ep=new NyARDoublePoint2d();\r
+ vec12_ep.vecSum(vec12,i_center);\r
+ //中心点から[0]->[3]と平行なベクトルの終点を計算\r
+ NyARDoublePoint2d vec03_ep=new NyARDoublePoint2d();\r
+ vec03_ep.vecSum(vec03,i_center); \r
+ //平均値\r
+ NyARDoublePoint2d cx_e2=new NyARDoublePoint2d();\r
+ cx_e2.x=(vec12_ep.x+vec03_ep.x)/2;\r
+ cx_e2.y=(vec12_ep.y+vec03_ep.y)/2;\r
+ \r
+ //cx_e2とベクトル[0]->[1]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e2,i_vertex[0],i_vertex[1],o_result[0][1]);\r
+ //ベクトル[3]->[2]との交差点を計算\r
+ solvCrossPoint(i_center,cx_e2,i_vertex[3],i_vertex[2],o_result[2][1]);\r
+ \r
+ \r
+*/ \r
+ \r
+ return;\r
+ }\r
+ \r
+ \r
+ \r
+ private void solvLinePointArray3(NyARDoublePoint2d i_canter,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+ {\r
+ NyARDoublePoint2d scale=new NyARDoublePoint2d();\r
+ //分割直線の計算(2=2分割,3=4分割,4=8分割)\r
+ int d=i_div;\r
+ NyARDoublePoint2d[] r=o_result[d/2];\r
+ //対角線Aを計算\r
+ r[0].x=i_vertex[0].x;\r
+ r[0].y=i_vertex[0].y;\r
+ r[d].x=i_vertex[2].x;\r
+ r[d].y=i_vertex[2].y;\r
+ scale.x=(i_canter.x-i_vertex[0].x)/(i_vertex[2].x-i_vertex[0].x);\r
+ scale.y=(i_canter.y-i_vertex[0].y)/(i_vertex[2].y-i_vertex[0].y);\r
+\r
+ solvLinePointArray_b(scale,0,d,r);\r
+ //対角線上にコピー\r
+ for(int i=0;i<=d;i++){\r
+ o_result[i][i].x=r[i].x; \r
+ o_result[i][i].y=r[i].y;\r
+ }\r
+ //対角線Bを計算\r
+ r[0].x=i_vertex[3].x;\r
+ r[0].y=i_vertex[3].y;\r
+ r[d].x=i_vertex[1].x;\r
+ r[d].y=i_vertex[1].y;\r
+ scale.x=(i_canter.x-i_vertex[3].x)/(i_vertex[1].x-i_vertex[3].x);\r
+ scale.y=(i_canter.y-i_vertex[3].y)/(i_vertex[1].y-i_vertex[3].y);\r
+ solvLinePointArray_b(scale,0,d,r);\r
+ //対角線上にコピー\r
+ for(int i=0;i<=d;i++){\r
+ o_result[d-i][i].x=r[i].x;\r
+ o_result[d-i][i].y=r[i].y;\r
+ }\r
+ //マップ作成\r
+ for(int i=0;i<=d;i++){\r
+ final NyARDoublePoint2d y1=o_result[i][i];\r
+ final NyARDoublePoint2d y2=o_result[d-i][i];\r
+ if(i==d/2){\r
+ continue;\r
+ }\r
+ for(int i2=0;i2<=d;i2++){\r
+ if(i==i2){\r
+ continue;\r
+ }\r
+ if(i==d-i2){\r
+ continue;\r
+ }\r
+ if(i2==d/2){\r
+ continue;\r
+ }\r
+ final NyARDoublePoint2d x1=o_result[i2][i2];\r
+ final NyARDoublePoint2d x2=o_result[i2][d-i2];\r
+ solvCrossPoint(y1,y2,x1,x2,o_result[i2][i]);\r
+ }\r
+ }\r
+\r
+ return;\r
+ } \r
+ /**\r
+ * 直線をscaleで2^n分割した配列を計算する。\r
+ * @param i_p1\r
+ * @param i_p2\r
+ * @param o_param\r
+ * @return\r
+ */\r
+ private void solvLinePointArray2(NyARDoublePoint2d i_canter,int i_div,NyARDoublePoint2d[] i_vertex,NyARDoublePoint2d[][] o_result)\r
+ {\r
+ NyARDoublePoint2d scale=new NyARDoublePoint2d();\r
+ //分割直線の計算(2=2分割,3=4分割,4=8分割)\r
+ int d=i_div;\r
+ NyARDoublePoint2d[] r=o_result[d/2];\r
+ //対角線Aを計算\r
+ r[0].x=i_vertex[0].x;\r
+ r[0].y=i_vertex[0].y;\r
+ r[d].x=i_vertex[2].x;\r
+ r[d].y=i_vertex[2].y;\r
+// scale.x=(i_canter.x-i_vertex[0].x)/(i_vertex[2].x-i_vertex[0].x);\r
+// scale.y=(i_canter.y-i_vertex[0].y)/(i_vertex[2].y-i_vertex[0].y);\r
+ double sx,kx,lx,sy,ky,ly;\r
+\r
+ sx=i_vertex[0].x;\r
+ kx=solvK(i_canter.x-sx,i_vertex[2].x-sx);\r
+ lx=solvL(kx,i_canter.x-sx);\r
+\r
+ sy=i_vertex[0].y;\r
+ ky=solvK(i_canter.y-sy,i_vertex[2].y-sy);\r
+ ly=solvL(kx,i_canter.y-sy);\r
+ \r
+ solvLinePointArray_b(scale,0,d,r);\r
+ //対角線上にコピー\r
+ for(int i=0;i<=d;i++){\r
+ o_result[i][i].x=sx+kx*lx;\r
+ o_result[i][i].y=sy+ky*ly;\r
+ kx*=kx;\r
+ ky*=ky;\r
+ }\r
+ \r
+ sx=i_vertex[3].x;\r
+ kx=solvK(i_canter.x-sx,i_vertex[1].x-sx);\r
+ lx=solvL(kx,i_canter.x-sx);\r
+\r
+ sy=i_vertex[3].y;\r
+ ky=solvK(i_canter.y-sy,i_vertex[1].y-sy);\r
+ ly=solvL(kx,i_canter.y-sy);\r
+ \r
+ solvLinePointArray_b(scale,0,d,r);\r
+ //対角線上にコピー\r
+ for(int i=0;i<=d;i++){\r
+ o_result[d-i][i].x=sx+kx*lx;\r
+ o_result[d-i][i].y=sy+ky*ly;\r
+ kx*=kx;\r
+ ky*=ky;\r
+ }\r
+ //マップ作成\r
+ for(int i=0;i<=d;i++){\r
+ final NyARDoublePoint2d y1=o_result[i][i];\r
+ final NyARDoublePoint2d y2=o_result[d-i][i];\r
+ if(i==d/2){\r
+ continue;\r
+ }\r
+ for(int i2=0;i2<=d;i2++){\r
+ if(i==i2){\r
+ continue;\r
+ }\r
+ if(i==d-i2){\r
+ continue;\r
+ }\r
+ if(i2==d/2){\r
+ continue;\r
+ }\r
+ final NyARDoublePoint2d x1=o_result[i2][i2];\r
+ final NyARDoublePoint2d x2=o_result[i2][d-i2];\r
+ solvCrossPoint(y1,y2,x1,x2,o_result[i2][i]);\r
+ }\r
+ }\r
+\r
+ return;\r
+ } \r
+\r
+ private void solvLinePointArray_b(NyARDoublePoint2d i_scale,int i_si,int i_ei,NyARDoublePoint2d[] o_result)\r
+ {\r
+ int ci=(i_ei-i_si)/2+i_si;\r
+ o_result[ci].x=i_scale.x*(o_result[i_ei].x-o_result[i_si].x)+o_result[i_si].x;\r
+ o_result[ci].y=i_scale.y*(o_result[i_ei].y-o_result[i_si].y)+o_result[i_si].y;\r
+ \r
+ if(ci-i_si==1){\r
+ return;\r
+ }\r
+ solvLinePointArray_b(i_scale,i_si,ci,o_result);\r
+ solvLinePointArray_b(i_scale,ci,i_ei,o_result);\r
+ return;\r
+ }\r
+ \r
+ private void solvCrossPoint(NyARIntPoint2d i_p1,NyARIntPoint2d i_p2,NyARIntPoint2d i_p3,NyARIntPoint2d i_p4,NyARDoublePoint2d o_result)\r
+ {\r
+ NyARDoublePoint2d va=new NyARDoublePoint2d(i_p2);\r
+ NyARDoublePoint2d vb=new NyARDoublePoint2d(i_p4);\r
+ va.vecSub(i_p1);\r
+ vb.vecSub(i_p3);\r
+ o_result.setValue(i_p3);\r
+ o_result.vecSub(i_p1);\r
+ va.vecMul(va, vb.vecCross(o_result)/vb.vecCross(va));\r
+ o_result.setValue(va);\r
+ o_result.vecAdd(i_p1);\r
+ return;\r
+ //V a=p2-p1;\r
+ //V b=p4-p3;\r
+ //return a1 + a * cross(b, b1-a1) / cross(b, a);\r
+ }\r
+ private void solvCrossPoint(NyARDoublePoint2d i_p1,NyARDoublePoint2d i_p2,NyARDoublePoint2d i_p3,NyARDoublePoint2d i_p4,NyARDoublePoint2d o_result)\r
+ {\r
+ NyARDoublePoint2d va=new NyARDoublePoint2d(i_p2);\r
+ NyARDoublePoint2d vb=new NyARDoublePoint2d(i_p4);\r
+ va.vecSub(i_p1);\r
+ vb.vecSub(i_p3);\r
+ o_result.setValue(i_p3);\r
+ o_result.vecSub(i_p1);\r
+ va.vecMul(va, vb.vecCross(o_result)/vb.vecCross(va));\r
+ o_result.setValue(va);\r
+ o_result.vecAdd(i_p1);\r
+ return;\r
+ //V a=p2-p1;\r
+ //V b=p4-p3;\r
+ //return a1 + a * cross(b, b1-a1) / cross(b, a);\r
+ } \r
+ double pow_1_3(double a)\r
+ {\r
+ double x = Math.pow(a, 1./3);\r
+ return (2*x+a/x/x)/3; // modifier\r
+ }\r
+ /*\r
+ * \r
+ * \r
+ * */\r
+ //(Sqrt(((3*Z*((-Z)/(3*Z))^2-(2*Z^2)/(3*Z)+Z-1)/Z)^3/27+(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)^2/(4*Z^2))-(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)/(2*Z))^(1/3)+(-((Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)/(2*Z)+Sqrt(((3*Z*((-Z)/(3*Z))^2-(2*Z^2)/(3*Z)+Z-1)/Z)^3/27+(Z*((-Z)/(3*Z))^2+Z*((-Z)/(3*Z))^3-((Z-1)*Z)/(3*Z)+Z-1)^2/(4*Z^2))))^(1/3)-Z/(3*Z)\r
+ private double solvK(double mp,double vp)\r
+ {\r
+ double Z=mp/vp;\r
+ double a=(Z-1);\r
+ double b=(3.0*Z);\r
+ double c=(a*Z);\r
+ double d=(2.0*Z*Z);//(2*Z^2)\r
+ double e=(4.0*Z*Z);//(4*Z^2)\r
+ double f=((-Z)/b);\r
+ double g=(Z*f*f+Z*f*f*f-c/b+Z-1);//(Z*f^2+Z*f^3-c/b+Z-1)\r
+ double h=(3.0*Z*f*f-d/b+Z-1.0);//(3*Z*f^2-d/b+Z-1)\r
+ double i=(h/Z);\r
+ Complex j=new Complex(0,i*i*i/27.0+g*g/e);//(0,i*i*i/27.0+g*g/e);\r
+// j.r=0;\r
+// j.i=Math.sqrt(-i*i*i/27.0+g*g/e);\r
+// j.sqrt(j);\r
+ Complex k=new Complex();\r
+ k.r=j.r-g/(2.0*Z);\r
+ k.i=j.i;\r
+ Complex l=new Complex();\r
+ l.r=-(g/(2.0*Z)+j.r);\r
+ l.i=-j.i;\r
+ \r
+ k.pow(k,1.0/3);\r
+ l.pow(l,1.0/3);\r
+ double fi=k.dist()+l.dist()-Z/b;\r
+ return fi;\r
+ }\r
+ private double solvL(double k,double mp)\r
+ {\r
+ return 100/(1+k*k+k*k*k+k);\r
+ }\r
+ \r
+ \r
+ public static void main(String[] args)\r
+ {\r
+\r
+ try {\r
+ NyARColorPatt_DiagonalRatio t = new NyARColorPatt_DiagonalRatio(3);\r
+ double k=t.solvK(60,100);\r
+ double l=t.solvL(k,60);\r
+ \r
+ // t.Test_arGetVersion();\r
+ NyARSquare s=new NyARSquare();\r
+ s.sqvertex[0].x=10;\r
+ s.sqvertex[0].y=10;\r
+ s.sqvertex[1].x=90;\r
+ s.sqvertex[1].y=0;\r
+ s.sqvertex[2].x=100;\r
+ s.sqvertex[2].y=100;\r
+ s.sqvertex[3].x=0;\r
+ s.sqvertex[3].y=100;\r
+ //t.getLineCrossPoint(s);\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit\r
+ * --------------------------------------------------------------------------------\r
+ * This work is based on the original ARToolKit developed by\r
+ * Hirokazu Kato\r
+ * Mark Billinghurst\r
+ * HITLab, University of Washington, Seattle\r
+ * http://www.hitl.washington.edu/artoolkit/\r
+ *\r
+ * The NyARToolkit is Java edition ARToolKit class library.\r
+ * Copyright (C)2008-2009 Ryo Iizuka\r
+ *\r
+ * This program is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ * \r
+ * For further information please contact.\r
+ * http://nyatla.jp/nyatoolkit/\r
+ * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.labeling.LabelOverlapChecker;\r
+import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.*;\r
+import jp.nyatla.nyartoolkit.core.param.NyARCameraDistortionFactor;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.Coord2SquareVertexIndexes;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
+import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+\r
+\r
+\r
+/**\r
+ * \r
+ *\r
+ */\r
+public class NyARSquareDetector_Vector\r
+{\r
+ private static final int AR_AREA_MAX = 100000;// #define AR_AREA_MAX 100000\r
+ private static final int AR_AREA_MIN = 70;// #define AR_AREA_MIN 70\r
+ private final int _width;\r
+ private final int _height;\r
+ private final int[] _xcoord;\r
+ private final int[] _ycoord;\r
+\r
+ private final NyARLabeling_Rle _labeling;\r
+\r
+ private final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> _overlap_checker = new LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo>(32,RleLabelFragmentInfoStack.RleLabelFragmentInfo.class);\r
+ private final SquareContourDetector_Vector _sqconvertor;\r
+ private final ContourPickup _cpickup=new ContourPickup();\r
+ private final RleLabelFragmentInfoStack _stack;\r
+ \r
+ private final int _max_coord;\r
+ /**\r
+ * 最大i_squre_max個のマーカーを検出するクラスを作成する。\r
+ * \r
+ * @param i_param\r
+ */\r
+ public NyARSquareDetector_Vector(NyARCameraDistortionFactor i_dist_factor_ref,NyARIntSize i_size) throws NyARException\r
+ {\r
+ this._width = i_size.w;\r
+ this._height = i_size.h;\r
+ //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。\r
+ this._labeling = new NyARLabeling_Rle(this._width,this._height);\r
+ this._labeling.setAreaRange(AR_AREA_MAX, AR_AREA_MIN);\r
+ this._sqconvertor=new SquareContourDetector_Vector(i_size,i_dist_factor_ref);\r
+ this._stack=new RleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数\r
+ \r
+\r
+ // 輪郭の最大長は画面に映りうる最大の長方形サイズ。\r
+ int number_of_coord = (this._width + this._height) * 2;\r
+\r
+ // 輪郭バッファ\r
+ this._max_coord = number_of_coord;\r
+ this._xcoord = new int[number_of_coord];\r
+ this._ycoord = new int[number_of_coord];\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * arDetectMarker2を基にした関数\r
+ * この関数はNyARSquare要素のうち、directionを除くパラメータを取得して返します。\r
+ * directionの確定は行いません。\r
+ * @param i_raster\r
+ * 解析する2値ラスタイメージを指定します。\r
+ * @param o_square_stack\r
+ * 抽出した正方形候補を格納するリスト\r
+ * @throws NyARException\r
+ */\r
+ public final void detectMarker(NyARGrayscaleRaster i_gs,int i_th,NyARSquareStack o_square_stack) throws NyARException\r
+ {\r
+ final RleLabelFragmentInfoStack flagment=this._stack;\r
+ final LabelOverlapChecker<RleLabelFragmentInfoStack.RleLabelFragmentInfo> overlap = this._overlap_checker;\r
+\r
+ // マーカーホルダをリセット\r
+ o_square_stack.clear();\r
+\r
+ // ラベル数が0ならここまで\r
+ final int label_num=this._labeling.labeling(i_gs,i_th, 0, i_gs.getHeight(), flagment);\r
+ if (label_num < 1) {\r
+ return;\r
+ }\r
+ //ラベルをソートしておく\r
+ flagment.sortByArea();\r
+ //ラベルリストを取得\r
+ RleLabelFragmentInfoStack.RleLabelFragmentInfo[] labels=flagment.getArray();\r
+\r
+ final int xsize = this._width;\r
+ final int ysize = this._height;\r
+ final int coord_max = this._max_coord;\r
+ int[] xcoord = this._xcoord;\r
+ int[] ycoord = this._ycoord;\r
+\r
+\r
+ //重なりチェッカの最大数を設定\r
+ overlap.setMaxLabels(label_num);\r
+\r
+ for (int i=0; i < label_num; i++) {\r
+ final RleLabelFragmentInfoStack.RleLabelFragmentInfo label_pt=labels[i];\r
+ final int label_area = label_pt.area;\r
+ \r
+ // クリップ領域が画面の枠に接していれば除外\r
+ if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){\r
+ continue;\r
+ }\r
+ if (label_pt.clip_t == 0 || label_pt.clip_b == ysize-1){\r
+ continue;\r
+ }\r
+ // 既に検出された矩形との重なりを確認\r
+ if (!overlap.check(label_pt)) {\r
+ // 重なっているようだ。\r
+ continue;\r
+ }\r
+ \r
+ // 輪郭を取得\r
+ final int coord_num = _cpickup.getContour(i_gs,i_th,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);\r
+ if (coord_num == coord_max) {\r
+ // 輪郭が大きすぎる。\r
+ continue;\r
+ }\r
+\r
+ //ここから先が輪郭分析\r
+ NyARSquare square_ptr = o_square_stack.prePush();\r
+ if(!this._sqconvertor.coordToSquare(i_gs,xcoord,ycoord,coord_num,label_area,square_ptr)){\r
+ o_square_stack.pop();// 頂点の取得が出来なかったので破棄\r
+ continue; \r
+ }\r
+ // 検出済の矩形の属したラベルを重なりチェックに追加する。\r
+ overlap.push(label_pt);\r
+ }\r
+ return;\r
+ }\r
+ /**\r
+ * デバック用API\r
+ * @return\r
+ */\r
+ public RleLabelFragmentInfoStack _getFragmentStack()\r
+ {\r
+ return this._stack;\r
+ }\r
+ /********************************************************************************\r
+ * \r
+ * 追加クラス \r
+ * \r
+ ********************************************************************************/\r
+ private class SquareContourDetector_Vector\r
+ {\r
+ private final NyARObserv2IdealMap2 _distmap;\r
+ private final int[] __detectMarker_mkvertex = new int[4];\r
+ private final Coord2SquareVertexIndexes _coord2vertex=new Coord2SquareVertexIndexes();\r
+ public SquareContourDetector_Vector(NyARIntSize i_size,NyARCameraDistortionFactor i_distfactor_ref)\r
+ {\r
+ this._distmap=new NyARObserv2IdealMap2(i_distfactor_ref,i_size);\r
+ return;\r
+ }\r
+\r
+ public boolean coordToSquare(NyARGrayscaleRaster i_raster,int[] i_xcoord,int[] i_ycoord,int i_coord_num,int i_label_area,NyARSquare o_square) throws NyARException\r
+ {\r
+\r
+ final int[] mkvertex = this.__detectMarker_mkvertex;\r
+\r
+ // 頂点情報を取得\r
+ if (!this._coord2vertex.getVertexIndexes(i_xcoord, i_ycoord,i_coord_num, i_label_area, mkvertex)) {\r
+ // 頂点の取得が出来なかったので破棄\r
+ return false;\r
+ } \r
+ // マーカーを検出\r
+ if (!getSquareLine(i_raster,mkvertex, i_xcoord, i_ycoord,i_coord_num, o_square)){\r
+ // 矩形が成立しなかった。\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+ /**\r
+ * 指定した範囲の輪郭点ベクトル・座標を、加算する。\r
+ * @param i_raster\r
+ * @param i_xcoord\r
+ * @param i_ycoord\r
+ * @param i_st\r
+ * @param i_ed\r
+ * @param o_vecsum\r
+ * @param o_possum\r
+ * @return\r
+ */\r
+ private boolean addCoordVecPos(NyARGrayscaleRaster i_raster,int[] i_xcoord, int[] i_ycoord,int i_st,int i_ed,NyARIntPoint2d io_vecsum)\r
+ {\r
+ int dxi,dyi;\r
+ //ベクトル分析\r
+ dxi=io_vecsum.x;\r
+ dyi=io_vecsum.y;\r
+ for(int i=i_st;i<i_ed;i++){\r
+ //境界に設置していたら失敗する。\r
+ if(i_xcoord[i]<1 || i_ycoord[i]<1 || i_xcoord[i]>=319 || i_ycoord[i]>=239){\r
+ return false;\r
+ }\r
+ //o_vecsumをワークに流用\r
+ i_raster.getPixelVector8(i_xcoord[i],i_ycoord[i],io_vecsum);\r
+ dxi+=io_vecsum.x;\r
+ dyi-=io_vecsum.y;\r
+ }\r
+ io_vecsum.x=dxi;\r
+ io_vecsum.y=dyi;\r
+ return true; \r
+ }\r
+ \r
+ \r
+ private NyARDoublePoint2d __work_pos=new NyARDoublePoint2d();\r
+ \r
+ private boolean getSquareLine(NyARGrayscaleRaster i_raster,int[] i_mkvertex, int[] i_xcoord, int[] i_ycoord,int i_cood_num, NyARSquare o_square) throws NyARException\r
+ {\r
+ final NyARLinear[] l_line = o_square.line;\r
+ final NyARDoublePoint2d[] l_sqvertex = o_square.sqvertex;\r
+ final NyARIntPoint2d[] l_imvertex = o_square.imvertex;\r
+ final NyARDoublePoint2d idealcenter=this.__work_pos;\r
+ \r
+ NyARIntPoint2d vecsum=new NyARIntPoint2d();\r
+ for (int i = 0; i < 4; i++){\r
+ //頂点を取得\r
+ int ver1=i_mkvertex[i];\r
+ int ver2=i_mkvertex[(i+1)%4];\r
+\r
+ int n,st,ed;\r
+ double w1;\r
+ //探索区間の決定\r
+ if(ver2>=i_mkvertex[i]){\r
+ //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき\r
+ w1 = (double) (ver2 - ver1 + 1) * 0.05 + 0.5;\r
+ //探索区間の決定\r
+ st = (int) (ver1+w1);\r
+ ed = (int) (ver2 - w1);\r
+ }else{\r
+ //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき\r
+ w1 = (double) (ver2+i_cood_num-ver1+1)%i_cood_num * 0.05 + 0.5;\r
+ //探索区間の決定\r
+ st = (int) (ver1+w1)%i_cood_num;\r
+ ed = (int) (ver2+i_cood_num-w1)%i_cood_num;\r
+ }\r
+ vecsum.x=vecsum.y=0;\r
+ //ベクトル分析\r
+ if(st<=ed){\r
+ //1区間\r
+ n = ed - st+1;\r
+ addCoordVecPos(i_raster,i_xcoord,i_ycoord,st,ed+1,vecsum);\r
+ this._distmap.getIdealCoodCenter(i_xcoord, i_ycoord,st,n,idealcenter);\r
+ }else{\r
+ //探索区間は2区間\r
+ double cx,cy;\r
+ n=ed+i_cood_num-st+1;\r
+ addCoordVecPos(i_raster,i_xcoord,i_ycoord,st,i_cood_num,vecsum);\r
+ addCoordVecPos(i_raster,i_xcoord,i_ycoord,0,ed,vecsum);\r
+ //輪郭の中心位置を計算\r
+ this._distmap.getIdealCoodCenter(i_xcoord, i_ycoord,st,i_cood_num-st,idealcenter);\r
+ cx=idealcenter.x;\r
+ cy=idealcenter.y;\r
+ this._distmap.getIdealCoodCenter(i_xcoord, i_ycoord,0,ed+1,idealcenter);\r
+ idealcenter.x=(idealcenter.x+cx)/2;\r
+ idealcenter.y=(idealcenter.y+cy)/2;\r
+ }\r
+ //中央値を歪修正(ほんとはピクセル単位にゆがみ矯正するべきだと思う)\r
+ \r
+ double l=Math.sqrt((double)(vecsum.x*vecsum.x+vecsum.y*vecsum.y));\r
+ final NyARLinear l_line_i = l_line[i];\r
+ //直交するベクトルを計算\r
+ l_line_i.dy = vecsum.x/l;\r
+ l_line_i.dx = -vecsum.y/l;\r
+ //cを計算\r
+ l_line_i.c = -(l_line_i.dy * (idealcenter.x) + l_line_i.dx * (idealcenter.y));\r
+ \r
+ // 頂点インデクスから頂点座標を得て保存\r
+ l_imvertex[i].x = i_xcoord[ver1];\r
+ l_imvertex[i].y = i_ycoord[ver1];\r
+ }\r
+ //線分式から頂点を計算\r
+ for(int i=0;i<4;i++)\r
+ {\r
+ if(!NyARLinear.crossPos(l_line[i],l_line[(i + 3) % 4],l_sqvertex[i])){\r
+ return false;\r
+ }\r
+ } \r
+ return true;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * 輪郭線の中心位置を計算する関数を追加したマップクラス\r
+ */\r
+ private class NyARObserv2IdealMap2 extends NyARObserv2IdealMap\r
+ {\r
+ public NyARObserv2IdealMap2(NyARCameraDistortionFactor i_distfactor,NyARIntSize i_screen_size)\r
+ {\r
+ super(i_distfactor,i_screen_size);\r
+ }\r
+ /**\r
+ * 歪み矯正した座標における、各座標の合計値を\r
+ * @param i_x_coord\r
+ * @param i_y_coord\r
+ * @param i_start\r
+ * @param i_num\r
+ * @param o_center\r
+ */\r
+ public void getIdealCoodCenter(int[] i_x_coord, int[] i_y_coord,int i_start, int i_num,NyARDoublePoint2d o_center)\r
+ {\r
+ int idx;\r
+ double x,y;\r
+ x=y=0;\r
+ final double[] mapx=this._mapx;\r
+ final double[] mapy=this._mapy;\r
+ final int stride=this._stride;\r
+ for (int j = 0; j < i_num; j++){\r
+ idx=i_x_coord[i_start + j]+i_y_coord[i_start + j]*stride;\r
+ x+=mapx[idx];\r
+ y+=mapy[idx];\r
+ }\r
+ o_center.x=x/(double)i_num;\r
+ o_center.y=y/(double)i_num;\r
+ return;\r
+ }\r
+ } \r
+}\r
+\r
+\r
+\r
--- /dev/null
+/* \r
+ * PROJECT: NyARToolkit JOGL sample program.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+import java.awt.event.*;\r
+import java.awt.*;\r
+import javax.media.Buffer;\r
+import javax.media.opengl.*;\r
+import com.sun.opengl.util.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.jogl.utils.*;\r
+/**\r
+ * 2種類の最適化アルゴリズムを比較するテストプログラム\r
+ *\r
+ */\r
+\r
+class Program implements JmfCaptureListener\r
+{\r
+ private OptimizeCompareTest _view1;\r
+ private OptimizeCompareTest _view2;\r
+ public Object _sync_object=new Object(); \r
+ public NyARParam _ar_param;\r
+ public NyARCode _ar_code;\r
+ private final static int SCREEN_X = 320;\r
+ private final static int SCREEN_Y = 240;\r
+ private JmfCaptureDevice _capture;\r
+ public GLNyARRaster_RGB _cap_image;\r
+ public Program(NyARParam i_param, NyARCode i_ar_code) throws NyARException\r
+ {\r
+ // キャプチャの準備\r
+ JmfCaptureDeviceList devlist = new JmfCaptureDeviceList();\r
+ this._capture = devlist.getDevice(0);\r
+ if (!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y, 30.0f)) {\r
+ throw new NyARException();\r
+ }\r
+ this._ar_param=i_param;\r
+ this._ar_code=i_ar_code;\r
+ this._capture.setOnCapture(this);\r
+ // GL対応のRGBラスタオブジェクト\r
+ this._cap_image = new GLNyARRaster_RGB(i_param, this._capture.getCaptureFormat()); \r
+ this._view1=new OptimizeCompareTest(this,NyARSingleDetectMarker.PF_NYARTOOLKIT);\r
+ this._view2=new OptimizeCompareTest(this,NyARSingleDetectMarker.PF_NYARTOOLKIT_ARTOOLKIT_FITTING);\r
+ this._capture.start();\r
+ return;\r
+ }\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+ synchronized (this._sync_object) {\r
+ this._cap_image.setBuffer(i_buffer);\r
+ this._view1.updateCapture(this._cap_image);\r
+ this._view2.updateCapture(this._cap_image);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ //GL API\r
+ void glDrawCube(GL i_gl)\r
+ {\r
+ // Colour cube data.\r
+ int polyList = 0;\r
+ float fSize = 0.5f;// マーカーサイズに対して0.5倍なので、4cmの立方体\r
+ int f, i;\r
+ float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };\r
+ float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };\r
+ int cube_num_faces = 6;\r
+ short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };\r
+\r
+ if (polyList == 0) {\r
+ polyList = i_gl.glGenLists(1);\r
+ i_gl.glNewList(polyList, GL.GL_COMPILE);\r
+ i_gl.glBegin(GL.GL_QUADS);\r
+ for (f = 0; f < cube_num_faces; f++)\r
+ for (i = 0; i < 4; i++) {\r
+ i_gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);\r
+ i_gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ }\r
+ i_gl.glEnd();\r
+ i_gl.glColor3f(0.0f, 0.0f, 0.0f);\r
+ for (f = 0; f < cube_num_faces; f++) {\r
+ i_gl.glBegin(GL.GL_LINE_LOOP);\r
+ for (i = 0; i < 4; i++)\r
+ i_gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ i_gl.glEnd();\r
+ }\r
+ i_gl.glEndList();\r
+ }\r
+\r
+ i_gl.glPushMatrix(); // Save world coordinate system.\r
+ i_gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker surface.\r
+ i_gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.\r
+ i_gl.glDisable(GL.GL_LIGHTING); // Just use colours.\r
+ i_gl.glCallList(polyList); // Draw the cube.\r
+ i_gl.glPopMatrix(); // Restore world coordinate system.\r
+ return;\r
+ }\r
+ \r
+}\r
+/**\r
+ * simpleLiteと同じようなテストプログラム 出来る限りARToolKitのサンプルと似せて作ってあります。 最も一致する"Hiro"マーカーを一つ選択して、その上に立方体を表示します。\r
+ * \r
+ */\r
+public class OptimizeCompareTest implements GLEventListener\r
+{\r
+ private final static int SCREEN_X = 320;\r
+\r
+ private final static int SCREEN_Y = 240;\r
+\r
+ private Animator _animator;\r
+ \r
+ private Program _parent;\r
+\r
+\r
+// private JmfCaptureDevice _capture;\r
+\r
+ private GL _gl;\r
+ private NyARGLUtil _glnya;\r
+\r
+ // NyARToolkit関係\r
+ private NyARSingleDetectMarker _nya;\r
+ private NyARParam _ar_param;\r
+\r
+ private double[] _camera_projection = new double[16];\r
+\r
+\r
+ public OptimizeCompareTest(Program i_program,int i_pf) throws NyARException\r
+ {\r
+ this._parent=i_program;\r
+ this._ar_param = i_program._ar_param;\r
+\r
+ Frame frame = new Frame("["+i_pf+"]");\r
+\r
+ // NyARToolkitの準備\r
+ this._nya = new NyARSingleDetectMarker(this._ar_param, i_program._ar_code, 80.0,i_program._cap_image.getBufferReader().getBufferType(),i_pf);\r
+ this._nya.setContinueMode(true);// ここをtrueにすると、transMatContinueモード(History計算)になります。\r
+ \r
+ // 3Dを描画するコンポーネント\r
+ GLCanvas canvas = new GLCanvas();\r
+ frame.add(canvas);\r
+ canvas.addGLEventListener(this);\r
+ frame.addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+\r
+ frame.setVisible(true);\r
+ Insets ins = frame.getInsets();\r
+ frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
+ canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
+ }\r
+\r
+ public void init(GLAutoDrawable drawable)\r
+ {\r
+ this._gl = drawable.getGL();\r
+ this._gl.glEnable(GL.GL_DEPTH_TEST);\r
+ this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
+ // NyARToolkitの準備\r
+ try {\r
+ // NyARToolkit用の支援クラス\r
+ _glnya = new NyARGLUtil(_gl);\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ // カメラパラメータの計算\r
+ this._glnya.toCameraFrustumRH(this._ar_param,this._camera_projection);\r
+ this._animator = new Animator(drawable);\r
+ this._animator.start();\r
+ return;\r
+ }\r
+\r
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
+ {\r
+ _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
+ _gl.glViewport(0, 0, width, height);\r
+\r
+ // 視体積の設定\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadIdentity();\r
+ // 見る位置\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ _gl.glLoadIdentity();\r
+ }\r
+\r
+ private boolean _is_marker_exist=false;\r
+ private NyARTransMatResult __display_transmat_result = new NyARTransMatResult();\r
+\r
+ private double[] __display_wk = new double[16];\r
+\r
+ public void display(GLAutoDrawable drawable)\r
+ {\r
+ NyARTransMatResult transmat_result = __display_transmat_result;\r
+ if (!this._parent._cap_image.hasData()) {\r
+ return;\r
+ }\r
+ // 背景を書く\r
+ this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.\r
+ this._glnya.drawBackGround(this._parent._cap_image, 1.0); \r
+ try{\r
+ synchronized(this._parent._sync_object){\r
+ // マーカーがあれば、立方体を描画\r
+ if (this._is_marker_exist){\r
+ // マーカーの一致度を調査するならば、ここでnya.getConfidence()で一致度を調べて下さい。\r
+ // Projection transformation.\r
+ _gl.glMatrixMode(GL.GL_PROJECTION);\r
+ _gl.glLoadMatrixd(_camera_projection, 0);\r
+ _gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ // Viewing transformation.\r
+ _gl.glLoadIdentity();\r
+ // 変換行列を取得\r
+ _nya.getTransmationMatrix(transmat_result);\r
+ // 変換行列をOpenGL形式に変換\r
+ _glnya.toCameraViewRH(transmat_result, __display_wk);\r
+ _gl.glLoadMatrixd(__display_wk, 0);\r
+ \r
+ // All other lighting and geometry goes here.\r
+ this._parent.glDrawCube(_gl);\r
+ }\r
+ }\r
+ Thread.sleep(1);// タスク実行権限を一旦渡す\r
+ }catch(Exception e){\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+\r
+ public void updateCapture(GLNyARRaster_RGB i_img)\r
+ {\r
+ try {\r
+ synchronized (this._parent._sync_object) {\r
+ this._is_marker_exist =this._nya.detectMarkerLite(i_img, 110);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
+ {\r
+ }\r
+\r
+ private final static String CARCODE_FILE = "../Data/patt.hiro";\r
+\r
+ private final static String PARAM_FILE = "../Data/camera_para.dat";\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ try {\r
+ NyARParam param = new NyARParam();\r
+ param.loadARParamFromFile(PARAM_FILE);\r
+ param.changeScreenSize(SCREEN_X, SCREEN_Y);\r
+\r
+ NyARCode code = new NyARCode(16, 16);\r
+ code.loadARPattFromFile(CARCODE_FILE);\r
+\r
+ new Program(param, code);\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ return;\r
+ }\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+import java.awt.Color;\r
+import java.awt.Frame;\r
+import java.awt.Graphics;\r
+import java.awt.Image;\r
+import java.awt.Insets;\r
+\r
+import javax.media.Buffer;\r
+import javax.media.format.VideoFormat;\r
+import javax.media.util.BufferToImage;\r
+\r
+import java.awt.color.ColorSpace;\r
+import java.awt.image.*;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.util.Date;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.jmf.utils.*;\r
+import jp.nyatla.nyartoolkit.detector.*;\r
+import jp.nyatla.nyartoolkit.nyidmarker.NyIdMarkerPickup;\r
+import jp.nyatla.nyartoolkit.core.transmat.*;\r
+import jp.nyatla.nyartoolkit.core.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+import jp.nyatla.nyartoolkit.core.pickup.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.gs2bin.*;\r
+import jp.nyatla.nyartoolkit.core.rasterfilter.rgb2bin.NyARRasterFilterBuilder_RgbToBin;\r
+import jp.nyatla.nyartoolkit.nyidmarker.*;\r
+import jp.nyatla.nyartoolkit.utils.j2se.*;\r
+import jp.nyatla.nyartoolkit.core.squaredetect.*;\r
+\r
+\r
+\r
+public class PattPickupTest extends Frame implements JmfCaptureListener\r
+{\r
+ private final String PARAM_FILE = "../Data/camera_para.dat";\r
+\r
+ private final static String CARCODE_FILE = "../Data/patt.hiro";\r
+\r
+ private static final long serialVersionUID = -2110888320986446576L;\r
+\r
+ private JmfCaptureDevice _capture;\r
+\r
+ private JmfNyARRaster_RGB _capraster;\r
+\r
+ private int W = 320;\r
+\r
+ private int H = 240;\r
+\r
+ private NyARParam _param;\r
+\r
+ private NyARBinRaster _bin_raster;\r
+\r
+ private NyARSquareStack _stack = new NyARSquareStack(100);\r
+\r
+ private NyARSingleDetectMarker detect;\r
+\r
+ public PattPickupTest() throws NyARException\r
+ {\r
+ setTitle("JmfCaptureTest");\r
+ Insets ins = this.getInsets();\r
+ this.setSize(640 + ins.left + ins.right, 480 + ins.top + ins.bottom);\r
+ JmfCaptureDeviceList dl = new JmfCaptureDeviceList();\r
+ this._capture = dl.getDevice(0);\r
+ if (!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_RGB, W, H, 30.0f)) {\r
+ if (!this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_YUV, W, H, 30.0f)) {\r
+ throw new NyARException("キャプチャフォーマットが見つかりません。");\r
+ }\r
+ }\r
+ NyARParam ar_param = new NyARParam();\r
+ ar_param.loadARParamFromFile(PARAM_FILE);\r
+ ar_param.changeScreenSize(W, H);\r
+\r
+ NyARCode code = new NyARCode(16, 16);\r
+ code.loadARPattFromFile(CARCODE_FILE);\r
+ this._capraster = new JmfNyARRaster_RGB(W, H, this._capture.getCaptureFormat());\r
+ this.detect = new NyARSingleDetectMarker(ar_param, code, 80, this._capraster.getBufferReader().getBufferType());\r
+ this._capture.setOnCapture(this);\r
+ this._bin_raster = new NyARBinRaster(W, H);\r
+ this._param = ar_param;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 矩形の矩形っぽい点数を返す。\r
+ * \r
+ * @param i_sq\r
+ * @return\r
+ */\r
+ private int getSQPoint(NyARSquare i_sq)\r
+ {\r
+ int lx1 = i_sq.imvertex[0].x - i_sq.imvertex[2].x;\r
+ int ly1 = i_sq.imvertex[0].y - i_sq.imvertex[2].y;\r
+ int lx2 = i_sq.imvertex[1].x - i_sq.imvertex[3].x;\r
+ int ly2 = i_sq.imvertex[1].y - i_sq.imvertex[3].y;\r
+ return (int) Math.sqrt((lx1 * lx1) + (ly1 * ly1)) * (int) Math.sqrt(((lx2 * lx2) + (ly2 * ly2)));\r
+ }\r
+\r
+ private final String data_file = "../Data/320x240ABGR.raw";\r
+\r
+ private INyARColorPatt _patt1 = new NyARColorPatt_O3(16, 16);\r
+\r
+ public void draw(INyARRgbRaster i_raster)\r
+ {\r
+ try {\r
+ Insets ins = this.getInsets();\r
+ Graphics g = getGraphics();\r
+\r
+ {// ピックアップ画像の表示\r
+ // 矩形抽出\r
+ INyARRasterFilter_Bin to_binfilter = new NyARRasterFilterBuilder_RgbToBin(110, i_raster.getBufferReader().getBufferType());\r
+ to_binfilter.doFilter(i_raster, this._bin_raster);\r
+ if (this.detect.detectMarkerLite(i_raster, 100)) {\r
+\r
+ NyARTransMatResult res = new NyARTransMatResult();\r
+ this.detect.getTransmationMatrix(res);\r
+ int max_point = 0;\r
+\r
+ // NyARSquare t=new NyARSquare();\r
+\r
+ TransformedBitmapPickup patt2 = new TransformedBitmapPickup(this._param.getPerspectiveProjectionMatrix(), 100, 100, 1);\r
+\r
+ BufferedImage sink = new BufferedImage(this._patt1.getWidth(), this._patt1.getHeight(), ColorSpace.TYPE_RGB);\r
+ BufferedImage sink2 = new BufferedImage(patt2.getWidth(), patt2.getHeight(), ColorSpace.TYPE_RGB);\r
+ patt2.pickupImage2d(i_raster,-20,-40,20,-80,res);\r
+ /*\r
+ * t.imvertex[0].x=(int)483.0639377595418; t.imvertex[0].y=(int)303.17616747966747;\r
+ * \r
+ * t.imvertex[1].x=(int)506.1019505415998; t.imvertex[1].y=(int)310.5313224526344;\r
+ * \r
+ * t.imvertex[2].x=(int)589.3605435960492; t.imvertex[2].y=(int)258.46261716798523;\r
+ * \r
+ * t.imvertex[3].x=(int)518.1385869954609; t.imvertex[3].y=(int)325.1434618295405;\r
+ */\r
+ Graphics g1, g2, g3;\r
+ /* {// ARToolkit\r
+ // 一番それっぽいパターンを取得\r
+ this._patt1.pickFromRaster(i_raster, t.imvertex);\r
+ Date d2 = new Date();\r
+ for (int i = 0; i < 10000; i++) {\r
+ this._patt1.pickFromRaster(i_raster, t.imvertex);\r
+ }\r
+ Date d = new Date();\r
+ System.out.println(d.getTime() - d2.getTime());\r
+\r
+ // パターンを書く\r
+ NyARRasterImageIO.copy(this._patt1, sink);\r
+ g1 = sink.getGraphics();\r
+ g1.setColor(Color.red);\r
+ }*/\r
+ {// 疑似アフィン変換\r
+ NyARRasterImageIO.copy(patt2, sink2);\r
+ g2 = sink2.getGraphics();\r
+ g2.setColor(Color.red);\r
+\r
+ }\r
+ g.drawImage(sink, ins.left + 320, ins.top, 128, 128, null);\r
+ g.drawImage(sink2, ins.left + 320, ins.top + 128, 128, 128, null);\r
+ // g.drawImage(sink3, ins.left + 100, ins.top + 240, this._patt3.getWidth() * 10, this._patt3.getHeight() * 10, null);\r
+ \r
+ }\r
+ {// 撮影画像\r
+ BufferedImage sink = new BufferedImage(i_raster.getWidth(), i_raster.getHeight(), ColorSpace.TYPE_RGB);\r
+ NyARRasterImageIO.copy(i_raster, sink);\r
+ g.drawImage(sink, ins.left, ins.top, this);\r
+ }\r
+\r
+ {// 信号取得テスト\r
+\r
+ }\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void onUpdateBuffer(Buffer i_buffer)\r
+ {\r
+ try {\r
+\r
+ {// ピックアップ画像の表示\r
+ // 矩形抽出\r
+ this._capraster.setBuffer(i_buffer);\r
+ draw(this._capraster);\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void startCapture()\r
+ {\r
+ try {\r
+ this._capture.start();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void startImage()\r
+ {\r
+ try {\r
+ // 試験イメージの読み出し(320x240 BGRAのRAWデータ)\r
+ File f = new File(data_file);\r
+ FileInputStream fs = new FileInputStream(data_file);\r
+ byte[] buf = new byte[(int) f.length() * 4];\r
+ fs.read(buf);\r
+ INyARRgbRaster ra = NyARRgbRaster_BGRA.wrap(buf, W, H);\r
+ draw(ra);\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ try {\r
+ PattPickupTest mainwin = new PattPickupTest();\r
+ mainwin.setVisible(true);\r
+ mainwin.startCapture();\r
+ // mainwin.startImage();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+\r
+}\r
--- /dev/null
+package jp.nyatla.nyartoolkit.dev;\r
+\r
+\r
+\r
+public class Solver\r
+{\r
+ public String[][] _data=new String[4][6];\r
+ public String[] _temp=new String[6];\r
+ public Solver()\r
+ {\r
+ this._data[0][0]="a";\r
+ this._data[0][1]="b";\r
+ this._data[0][2]="c";\r
+ this._data[0][3]="d";\r
+ this._data[0][4]="e";\r
+ this._data[0][5]="1";\r
+ \r
+ this._data[1][0]="f";\r
+ this._data[1][1]="g";\r
+ this._data[1][2]="h";\r
+ this._data[1][3]="i";\r
+ this._data[1][4]="j";\r
+ this._data[1][5]="1";\r
+ \r
+ this._data[2][0]="k";\r
+ this._data[2][1]="l";\r
+ this._data[2][2]="m";\r
+ this._data[2][3]="n";\r
+ this._data[2][4]="o";\r
+ this._data[2][5]="1";\r
+\r
+ this._data[3][0]="p";\r
+ this._data[3][1]="q";\r
+ this._data[3][2]="r";\r
+ this._data[3][3]="s";\r
+ this._data[3][4]="t";\r
+ this._data[3][5]="1";\r
+ }\r
+ public void dump()\r
+ {\r
+ for(int i=0;i<this._data.length;i++){\r
+ for(int i2=0;i2<this._data[i].length;i2++){\r
+ System.out.print(this._data[i][i2]+" , ");\r
+ } \r
+ System.out.println(" ");\r
+ }\r
+ }\r
+ public boolean isSingle(String i_str)\r
+ {\r
+ int c=0;\r
+ for(int i=0;i<i_str.length();i++){\r
+ if(i_str.charAt(i)=='('){\r
+ c++;\r
+ }\r
+ if(i_str.charAt(i)==')'){\r
+ c--;\r
+ if(c==0 && i!=i_str.length()-1){\r
+ return false;//括弧必要\r
+ }\r
+ }\r
+ }\r
+ return true;//括弧不要\r
+ }\r
+ \r
+ public void div(int i_r,String i_e,String[] o_row) throws Exception\r
+ {\r
+ if(i_e=="0"){\r
+ throw new Exception(); \r
+ }else if(i_e=="1"){\r
+ return;\r
+ }\r
+ String[] l=this._data[i_r];\r
+ for(int i=0;i<o_row.length;i++){\r
+ if(l[i]==i_e){\r
+ o_row[i]="1";\r
+ }else if(l[i]=="0"){\r
+ o_row[i]="0";\r
+ }else{\r
+ String s1=isSingle(l[i])?l[i]:"("+l[i]+")";\r
+ String s2=isSingle(i_e)?i_e:"("+i_e+")";\r
+ o_row[i]="("+s1+"/"+s2+")";\r
+ }\r
+ }\r
+ }\r
+ public void mul(int i_r,String i_e,String[] o_row)\r
+ {\r
+ String[] l=this._data[i_r];\r
+ if(i_e=="0"){\r
+ for(int i=0;i<o_row.length;i++){\r
+ o_row[i]="0";\r
+ }\r
+ }else if(i_e=="1"){\r
+ return;\r
+ }else{\r
+ for(int i=0;i<o_row.length;i++){\r
+ if(l[i]=="0"){\r
+ o_row[i]="0";\r
+ }else if(l[i]=="1"){\r
+ o_row[i]=i_e;\r
+ }else{\r
+ String s1=isSingle(l[i])?l[i]:"("+l[i]+")";\r
+ String s2=isSingle(i_e)?i_e:"("+i_e+")";\r
+ o_row[i]="("+s1+"*"+s2+")";\r
+ }\r
+ }\r
+ }\r
+ }\r
+ public void subRow(int i_r1,String[] i_r,String[] o_row)\r
+ {\r
+ String[] l1=this._data[i_r1];\r
+ String[] l2=i_r;\r
+ for(int i=0;i<o_row.length;i++){\r
+ if(l1[i]=="0"){\r
+ o_row[i]=l2[i];\r
+ }else if(l2[i]=="0"){\r
+ o_row[i]=l1[i];\r
+ }else if(l2[i]==l1[i]){\r
+ o_row[i]="0";\r
+ }else{\r
+ String s1=isSingle(l1[i])?l1[i]:"("+l1[i]+")";\r
+ String s2=isSingle(l2[i])?l2[i]:"("+l2[i]+")";\r
+ o_row[i]="("+s1+"-"+s2+")";\r
+ }\r
+ }\r
+ }\r
+ public static void main(String[] args)\r
+ {\r
+ try {\r
+ Solver n=new Solver();\r
+\r
+ for(int i=0;i<4;i++){\r
+ for(int i2=0;i2<i;i2++){\r
+ n.mul(i2,n._data[i][i2],n._temp);\r
+ n.subRow(i,n._temp,n._data[i]); \r
+ }\r
+ n.div(i,n._data[i][i],n._data[i]);\r
+ }\r
+ n.dump();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ } \r
+}\r